Skip to content

Commit

Permalink
[APITools] Simplify/Unify file write and avoid intermediate strings
Browse files Browse the repository at this point in the history
  • Loading branch information
HannesWell committed Mar 26, 2024
1 parent 203a2c1 commit 79c5700
Show file tree
Hide file tree
Showing 27 changed files with 216 additions and 538 deletions.
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 @@ public void generateAPIFile() {
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 @@ public void generateAPIFile() {
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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

0 comments on commit 79c5700

Please sign in to comment.