Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[APITools] Simplify/Unify file write and avoid intermediate strings #1201

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -16,11 +16,9 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
Expand Down Expand Up @@ -65,6 +63,7 @@
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.eclipse.pde.api.tools.model.tests.TestSuiteHelper;
import org.eclipse.pde.api.tools.tests.util.FileUtils;
import org.eclipse.pde.api.tools.tests.util.ProjectUtils;
Expand All @@ -75,6 +74,7 @@
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.osgi.service.prefs.BackingStoreException;
import org.w3c.dom.Document;

import junit.framework.Test;
import junit.framework.TestSuite;
Expand Down Expand Up @@ -335,7 +335,7 @@ protected static void exportApiComponent(IProject project, IApiComponent apiComp
// create API Description, this should be the first step because
// otherwise we might trigger a resource change that maybe invalidates
// our component before we can process it!
String xml = componentToXml(apiComponent);
Document xml = componentToXml(apiComponent);
// now we have the xml and can go on...
File root = baselineLocation.toFile();
File componentDir = new File(root, project.getName());
Expand All @@ -357,14 +357,10 @@ protected static void exportApiComponent(IProject project, IApiComponent apiComp
IFolder output = project.getFolder("bin"); //$NON-NLS-1$
FileUtils.copyFolder(output, componentDir);
// copy description
File desc = new File(componentDir, ".api_description"); //$NON-NLS-1$
desc.createNewFile();
try (FileOutputStream stream = new FileOutputStream(desc)) {
stream.write(xml.getBytes(StandardCharsets.UTF_8));
}
Util.writeDocumentToFile(xml, componentDir.toPath().resolve(".api_description")); //$NON-NLS-1$
}

private static String componentToXml(IApiComponent apiComponent) throws CoreException {
private static Document componentToXml(IApiComponent apiComponent) throws CoreException {
ApiDescriptionXmlCreator visitor = new ApiDescriptionXmlCreator(apiComponent);
apiComponent.getApiDescription().accept(visitor, null);
return visitor.getXML();
Expand Down
Expand Up @@ -157,7 +157,7 @@ public void test5() {
try {
DeltaXmlVisitor xmlVisitor = new DeltaXmlVisitor();
delta.accept(xmlVisitor);
assertNotNull("No XML", xmlVisitor.getXML()); //$NON-NLS-1$
assertNotNull("No XML", xmlVisitor.getDocument()); //$NON-NLS-1$
} catch (CoreException e) {
ApiPlugin.log(e);
}
Expand Down Expand Up @@ -2469,7 +2469,7 @@ public void test99() {
try {
DeltaXmlVisitor xmlVisitor = new DeltaXmlVisitor();
delta.accept(xmlVisitor);
assertNotNull("No XML", xmlVisitor.getXML()); //$NON-NLS-1$
assertNotNull("No XML", xmlVisitor.getDocument()); //$NON-NLS-1$
} catch (CoreException e) {
ApiPlugin.log(e);
}
Expand Down
Expand Up @@ -48,6 +48,7 @@
import org.eclipse.pde.api.tools.internal.util.Signatures;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.junit.Test;
import org.w3c.dom.Document;

/**
* Tests API manifest implementation.
Expand Down Expand Up @@ -347,7 +348,7 @@ public void endVisitElement(IElementDescriptor element, IApiAnnotations descript
* @return XML for the API description
* @throws CoreException if something goes terribly wrong
*/
private String getApiDescriptionXML(IApiComponent apiComponent) throws CoreException {
private Document getApiDescriptionXML(IApiComponent apiComponent) throws CoreException {
ApiDescriptionXmlCreator xmlVisitor = new ApiDescriptionXmlCreator(apiComponent);
apiComponent.getApiDescription().accept(xmlVisitor, null);
return xmlVisitor.getXML();
Expand Down Expand Up @@ -377,7 +378,7 @@ public void testPersistRestoreXML() throws CoreException, IOException {

// write back to XML and then re-create
IApiComponent component = TestSuiteHelper.createTestingApiComponent("test", "test", settings); //$NON-NLS-1$ //$NON-NLS-2$
String writeXML = getApiDescriptionXML(component);
String writeXML = Util.serializeDocument(getApiDescriptionXML(component));

IApiDescription restored = new ApiDescription(null);
ApiDescriptionProcessor.annotateApiSettings(null, restored, writeXML);
Expand Down
Expand Up @@ -114,17 +114,13 @@ protected IStatus run(IProgressMonitor monitor) {
return Status.error(ActionMessages.ExportSessionAction_failed_to_create_parent_folders);
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(xmlOutputFile))) {
DeltaXmlVisitor visitor = new DeltaXmlVisitor();
Object data = activeSession.getModel().getRoot().getData();
if (data instanceof IDelta) {
IDelta delta = (IDelta) data;
progress.split(25);
delta.accept(visitor);
writer.write(visitor.getXML());
writer.flush();
progress.worked(25);
}
DeltaXmlVisitor visitor = new DeltaXmlVisitor();
Object data = activeSession.getModel().getRoot().getData();
if (data instanceof IDelta delta) {
progress.split(25);
delta.accept(visitor);
Util.writeDocumentToFile(visitor.getDocument(), xmlOutputFile.toPath());
progress.worked(25);
}
} catch (IOException | CoreException e) {
ApiPlugin.log(e);
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
Expand All @@ -48,6 +49,7 @@
import org.eclipse.pde.api.tools.internal.util.Util;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
Expand Down Expand Up @@ -151,25 +153,15 @@
return;
}
// check if the .api_description file exists
File targetProjectFolder = new File(this.targetFolder);
if (!targetProjectFolder.exists()) {
targetProjectFolder.mkdirs();
} else if (!targetProjectFolder.isDirectory()) {
Path apiDescriptionFile = Path.of(this.targetFolder, IApiCoreConstants.API_DESCRIPTION_XML_NAME);
Path projectFolder = apiDescriptionFile.getParent();
if (Files.exists(projectFolder) && !Files.isDirectory(projectFolder)) {
if (this.debug) {
System.err.println("Must be a directory : " + this.targetFolder); //$NON-NLS-1$
}
throw new IllegalArgumentException(
NLS.bind(CoreMessages.api_generation_targetFolderNotADirectory, this.targetFolder));
}
File apiDescriptionFile = new File(targetProjectFolder, IApiCoreConstants.API_DESCRIPTION_XML_NAME);
if (apiDescriptionFile.exists()) {
// get rid of the existing one
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=414053
if (this.debug) {
System.out.println("Existing api description file deleted"); //$NON-NLS-1$
}
apiDescriptionFile.delete();
}
// create the directory class file container used to resolve
// signatures during tag scanning
String[] allBinaryLocations = this.binaryLocations.split(File.pathSeparator);
Expand Down Expand Up @@ -282,8 +274,8 @@
try {
ApiDescriptionXmlCreator xmlVisitor = new ApiDescriptionXmlCreator(this.projectName, this.projectName);
apiDescription.accept(xmlVisitor, null);
String xml = xmlVisitor.getXML();
Util.saveFile(apiDescriptionFile, xml);
Document xml = xmlVisitor.getXML();
Util.writeDocumentToFile(xml, apiDescriptionFile);
} catch (CoreException | IOException e) {
ApiPlugin.log(e);
}
Expand Down Expand Up @@ -370,7 +362,7 @@
*/
private String resolveCompliance(Map<String, String> manifestmap) {
if (manifestmap != null) {
String eename = manifestmap.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);

Check warning on line 365 in apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/APIFileGenerator.java

View check run for this annotation

Jenkins - eclipse-pde / Compiler and API Tools

Deprecation

NORMAL: The field Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT is deprecated
if (eename != null) {
if ("J2SE-1.4".equals(eename)) { //$NON-NLS-1$
return JavaCore.VERSION_1_4;
Expand Down
Expand Up @@ -16,12 +16,10 @@
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -322,7 +320,7 @@ private String getDefaultProfilePref() {
* Persists all of the cached elements to individual xml files named with
* the id of the API baseline
*/
private void persistStateCache() throws CoreException, IOException {
private void persistStateCache() throws CoreException {
if (savelocation == null) {
return;
}
Expand All @@ -333,45 +331,31 @@ private void persistStateCache() throws CoreException, IOException {
node.remove(DEFAULT_BASELINE);
}
if (baselinecache != null && !hasinfos.isEmpty()) {
File dir = new File(savelocation.toOSString());
Files.createDirectories(dir.toPath());
IApiBaseline baseline = null;
Path dir = savelocation.toPath();
for (Entry<String, IApiBaseline> entry : baselinecache.entrySet()) {
String id = entry.getKey();
baseline = entry.getValue();
IApiBaseline baseline = entry.getValue();
if (!isBaselineLoaded(baseline)) {
continue;
}
File file = savelocation.append(id + BASELINE_FILE_EXTENSION).toFile();
if (!file.exists()) {
try {
Files.createFile(file.toPath());
} catch (IOException ioe) {
ApiPlugin.log(new IOException("Unable to save API baseline with id: '" + id + "'", ioe)); //$NON-NLS-1$ //$NON-NLS-2$
continue;
}
}
try (FileOutputStream fout = new FileOutputStream(file)) {
writeBaselineDescription(baseline, fout);
// need to save the api baseline state in order to be able
// to reload it later
handlecache.put(baseline.getName(), file.getAbsolutePath());
fout.flush();
}
Path file = dir.resolve(id + BASELINE_FILE_EXTENSION);
writeBaselineDescription(baseline, file);
// need to save the api baseline state in order to be able
// to reload it later
handlecache.put(baseline.getName(), file.toAbsolutePath().toString());
}
}
}

/**
* Writes out the current state of the {@link IApiBaseline} as XML to the
* given output stream
* Writes the current state of the {@link IApiBaseline} as XML to the given file
*/
private void writeBaselineDescription(IApiBaseline baseline, OutputStream stream) throws CoreException {
String xml = getProfileXML(baseline);
private void writeBaselineDescription(IApiBaseline baseline, Path file) throws CoreException {
Document xml = getProfileXML(baseline);
try {
stream.write(xml.getBytes(StandardCharsets.UTF_8));
Util.writeDocumentToFile(xml, file);
} catch (IOException e) {
throw new CoreException(Status.error("Error writing pofile descrition", e)); //$NON-NLS-1$
throw new CoreException(Status.error("Error writing profile descrition", e)); //$NON-NLS-1$
}
}

Expand All @@ -383,7 +367,7 @@ private void writeBaselineDescription(IApiBaseline baseline, OutputStream stream
* @throws CoreException if an exception occurs while retrieving the xml
* string representation
*/
private String getProfileXML(IApiBaseline baseline) throws CoreException {
private Document getProfileXML(IApiBaseline baseline) throws CoreException {
Document document = Util.newDocument();
Element root = document.createElement(IApiXmlConstants.ELEMENT_APIPROFILE);
document.appendChild(root);
Expand Down Expand Up @@ -417,7 +401,7 @@ private String getProfileXML(IApiBaseline baseline) throws CoreException {
// clear the temporary hashset
allComponentSet.clear();
}
return Util.serializeDocument(document);
return document;
}

/**
Expand Down Expand Up @@ -483,7 +467,7 @@ public IApiComponent[] readBaselineComponents(ApiBaseline baseline, InputStream
}
}
restored = components.toArray(new IApiComponent[components.size()]);
// Avoid unstable bundle traversal order to simplify our life
// Avoid unstable bundle traversal order to simplify our life
Arrays.sort(restored, (o1, o2) -> o1.getName().compareTo(o2.getName()));
}
} catch (IOException | SAXException e) {
Expand Down Expand Up @@ -512,13 +496,9 @@ public void saving(ISaveContext context) throws CoreException {
if (!fNeedsSaving) {
return;
}
try {
persistStateCache();
cleanStateCache();
fNeedsSaving = false;
} catch (IOException e) {
ApiPlugin.log(e);
}
persistStateCache();
cleanStateCache();
fNeedsSaving = false;
}

/**
Expand Down
Expand Up @@ -16,6 +16,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -49,6 +50,7 @@
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
import org.eclipse.pde.api.tools.internal.provisional.scanner.ScannerMessages;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
Expand Down Expand Up @@ -227,11 +229,10 @@ public synchronized void saving(ISaveContext context) throws CoreException {
IJavaProject project = entry.getKey();
ProjectApiDescription desc = (ProjectApiDescription) entry.getValue();
if (desc.isModified()) {
File dir = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName()).toFile();
dir.mkdirs();
String xml = desc.getXML();
Path dir = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName()).toPath();
Document xml = desc.getXML();
try {
Util.saveFile(new File(dir, IApiCoreConstants.API_DESCRIPTION_XML_NAME), xml);
Util.writeDocumentToFile(xml, dir.resolve(IApiCoreConstants.API_DESCRIPTION_XML_NAME));
desc.setModified(false);
} catch (IOException e) {
abort(MessageFormat.format(ScannerMessages.ApiDescriptionManager_0, project.getElementName()), e);
Expand Down
Expand Up @@ -136,13 +136,12 @@ public void endVisitElement(IElementDescriptor element, IApiAnnotations descript
}

/**
* Returns the settings as a UTF-8 string containing XML.
* Returns the settings as a XML {@link Document}.
*
* @return XML
* @throws CoreException if something goes wrong
*/
public String getXML() throws CoreException {
return Util.serializeDocument(fDoc);
public Document getXML() {
return fDoc;
}

@Override
Expand Down