package org.eclipse.ltk.internal.core.refactoring;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ltk.core.refactoring.IRefactoringCoreStatusCodes;
import org.eclipse.ltk.core.refactoring.RefactoringContribution;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringSessionDescriptor;
import org.eclipse.ltk.internal.core.refactoring.history.DefaultRefactoringDescriptor;
import org.eclipse.ltk.internal.core.refactoring.history.RefactoringContributionManager;
public final class RefactoringSessionReader extends DefaultHandler {
private String = null;
private final String fProject;
private final boolean fCreateDefaultDescriptors;
private List<RefactoringDescriptor> fRefactoringDescriptors= null;
private boolean fSessionFound= false;
private String fVersion= null;
private Locator fLocator;
public RefactoringSessionReader(boolean createDefaultDescriptors, String project) {
fCreateDefaultDescriptors= createDefaultDescriptors;
fProject= project;
}
private SAXParser createParser(final SAXParserFactory factory) throws ParserConfigurationException, SAXException {
final SAXParser parser= factory.newSAXParser();
final XMLReader reader= parser.getXMLReader();
try {
reader.setFeature("http://xml.org/sax/features/validation", false);
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
} catch (SAXNotRecognizedException | SAXNotSupportedException exception) {
}
return parser;
}
public RefactoringSessionDescriptor readSession(final InputSource source) throws CoreException {
fSessionFound= false;
try {
source.setSystemId("/");
createParser(SAXParserFactory.newInstance()).parse(source, this);
if (!fSessionFound)
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR, RefactoringCoreMessages.RefactoringSessionReader_no_session, null));
if (fRefactoringDescriptors != null) {
if (fVersion == null || "".equals(fVersion))
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.MISSING_REFACTORING_HISTORY_VERSION, RefactoringCoreMessages.RefactoringSessionReader_missing_version_information, null));
if (!IRefactoringSerializationConstants.CURRENT_VERSION.equals(fVersion))
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.UNSUPPORTED_REFACTORING_HISTORY_VERSION, RefactoringCoreMessages.RefactoringSessionReader_unsupported_version_information, null));
return new RefactoringSessionDescriptor(fRefactoringDescriptors.toArray(new RefactoringDescriptor[fRefactoringDescriptors.size()]), fVersion, fComment);
}
} catch (SAXParseException exception) {
String message= Messages.format(RefactoringCoreMessages.RefactoringSessionReader_invalid_contents_at,
new Object[] {
Integer.toString(exception.getLineNumber()),
Integer.toString(exception.getColumnNumber())
});
throwCoreException(exception, message);
} catch (IOException | ParserConfigurationException | SAXException exception) {
throwCoreException(exception, exception.getLocalizedMessage());
} finally {
fRefactoringDescriptors= null;
fVersion= null;
fComment= null;
fLocator= null;
}
return null;
}
private void throwCoreException(Exception exception, String message) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR,
RefactoringCorePlugin.getPluginId(),
IRefactoringCoreStatusCodes.REFACTORING_HISTORY_IO_ERROR,
message,
exception));
}
@Override
public void setDocumentLocator(Locator locator) {
fLocator= locator;
}
@Override
public void startElement(final String uri, final String localName, final String qualifiedName, final Attributes attributes) throws SAXException {
if (IRefactoringSerializationConstants.ELEMENT_REFACTORING.equals(qualifiedName)) {
final int length= attributes.getLength();
final Map<String, String> map= new HashMap<>(length);
String id= "";
String stamp= "";
String description= "";
String comment= null;
String flags= "0";
String project= null;
for (int index= 0; index < length; index++) {
final String name= attributes.getQName(index);
final String value= attributes.getValue(index);
if (IRefactoringSerializationConstants.ATTRIBUTE_ID.equals(name)) {
id= value;
} else if (IRefactoringSerializationConstants.ATTRIBUTE_STAMP.equals(name)) {
stamp= value;
} else if (IRefactoringSerializationConstants.ATTRIBUTE_DESCRIPTION.equals(name)) {
description= value;
} else if (IRefactoringSerializationConstants.ATTRIBUTE_FLAGS.equals(name)) {
flags= value;
} else if (IRefactoringSerializationConstants.ATTRIBUTE_COMMENT.equals(name)) {
if (!"".equals(value))
comment= value;
} else if (IRefactoringSerializationConstants.ATTRIBUTE_PROJECT.equals(name)) {
project= value;
} else if (!"".equals(name)) {
map.put(name, value);
}
}
int flag= 0;
try {
flag= Integer.parseInt(flags);
} catch (NumberFormatException exception) {
}
RefactoringDescriptor descriptor= null;
if (fCreateDefaultDescriptors) {
descriptor= new DefaultRefactoringDescriptor(id, project, description, comment, map, flag);
} else {
if (fProject != null && project == null) {
project= fProject;
}
try {
descriptor= RefactoringContributionManager.getInstance().createDescriptor(id, project, description, comment, map, flag);
} catch (RuntimeException e) {
throw new SAXParseException(RefactoringCoreMessages.RefactoringSessionReader_invalid_values_in_xml, fLocator, e) {
private static final long serialVersionUID= 1L;
@Override
public Throwable getCause() {
return getException();
}
};
}
}
try {
descriptor.setTimeStamp(Long.valueOf(stamp).longValue());
} catch (NumberFormatException exception) {
}
if (fRefactoringDescriptors == null)
fRefactoringDescriptors= new ArrayList<>();
fRefactoringDescriptors.add(descriptor);
} else if (IRefactoringSerializationConstants.ELEMENT_SESSION.equals(qualifiedName)) {
fSessionFound= true;
final String version= attributes.getValue(IRefactoringSerializationConstants.ATTRIBUTE_VERSION);
if (version != null && !"".equals(version))
fVersion= version;
fComment= attributes.getValue(IRefactoringSerializationConstants.ATTRIBUTE_COMMENT);
}
}
}