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.
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 @@ 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
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

0 comments on commit 79c5700

Please sign in to comment.