blob: f3890be91c0da9eb695404e727880305456179ab [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ltk.internal.core.refactoring;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.runtime.Assert;
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.RefactoringDescriptor;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Transformer for XML-based refactoring histories.
*
* @since 3.2
*/
public final class RefactoringSessionTransformer {
/** The current document, or <code>null</code> */
private Document fDocument= null;
/** Should project information be included? */
private final boolean fProjects;
/** The current refactoring node, or <code>null</code> */
private Node fRefactoring= null;
/** The current session node, or <code>null</code> */
private Node fSession= null;
/**
* Creates a new refactoring session transformer.
*
* @param projects
* <code>true</code> to include project information,
* <code>false</code> otherwise
*/
public RefactoringSessionTransformer(final boolean projects) {
fProjects= projects;
}
/**
* Begins the transformation of a refactoring specified by the given
* arguments.
* <p>
* Calls to
* {@link RefactoringSessionTransformer#beginRefactoring(String, long, String, String, String, int)}
* must be balanced with calls to
* {@link RefactoringSessionTransformer#endRefactoring()}. If the
* transformer is already processing a refactoring, nothing happens.
* </p>
*
* @param id
* the unique identifier of the refactoring
* @param stamp
* the time stamp of the refactoring, or <code>-1</code>
* @param project
* the non-empty name of the project this refactoring is
* associated with, or <code>null</code>
* @param description
* a human-readable description of the refactoring
* @param comment
* the comment associated with the refactoring, or
* <code>null</code>
* @param flags
* the flags associated with refactoring
* @throws CoreException
* if an error occurs while creating a new refactoring
*/
public void beginRefactoring(final String id, long stamp, final String project, final String description, final String comment, final int flags) throws CoreException {
Assert.isNotNull(id);
Assert.isNotNull(description);
Assert.isTrue(flags >= RefactoringDescriptor.NONE);
try {
if (fDocument == null)
fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
} catch (ParserConfigurationException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_IO_ERROR, exception.getLocalizedMessage(), null));
} catch (FactoryConfigurationError exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_IO_ERROR, exception.getLocalizedMessage(), null));
}
if (fRefactoring == null) {
try {
fRefactoring= fDocument.createElement(IRefactoringSerializationConstants.ELEMENT_REFACTORING);
final NamedNodeMap attributes= fRefactoring.getAttributes();
Attr attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_ID);
attribute.setValue(id);
attributes.setNamedItem(attribute);
if (stamp >= 0) {
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_STAMP);
attribute.setValue(new Long(stamp).toString());
attributes.setNamedItem(attribute);
}
if (flags != RefactoringDescriptor.NONE) {
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_FLAGS);
attribute.setValue(String.valueOf(flags));
attributes.setNamedItem(attribute);
}
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_DESCRIPTION);
attribute.setValue(description);
attributes.setNamedItem(attribute);
if (comment != null && !"".equals(comment)) { //$NON-NLS-1$
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_COMMENT);
attribute.setValue(comment);
attributes.setNamedItem(attribute);
}
if (project != null && fProjects) {
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_PROJECT);
attribute.setValue(project);
attributes.setNamedItem(attribute);
}
if (fSession == null)
fDocument.appendChild(fRefactoring);
else
fSession.appendChild(fRefactoring);
} catch (DOMException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR, exception.getLocalizedMessage(), null));
}
}
}
/**
* Begins the transformation of a refactoring session.
* <p>
* Calls to {@link RefactoringSessionTransformer#beginSession(String)} must
* be balanced with calls to
* {@link RefactoringSessionTransformer#endSession()}. If the transformer
* is already processing a session, nothing happens.
* </p>
*
* @param comment
* the comment associated with the refactoring session, or
* <code>null</code>
* @throws CoreException
* if an error occurs while creating a new session
*/
public void beginSession(final String comment) throws CoreException {
if (fDocument == null) {
try {
fDocument= DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
fSession= fDocument.createElement(IRefactoringSerializationConstants.ELEMENT_SESSION);
Attr attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_VERSION);
attribute.setValue(IRefactoringSerializationConstants.CURRENT_VERSION);
fSession.getAttributes().setNamedItem(attribute);
if (comment != null && !"".equals(comment)) { //$NON-NLS-1$
attribute= fDocument.createAttribute(IRefactoringSerializationConstants.ATTRIBUTE_COMMENT);
attribute.setValue(comment);
fSession.getAttributes().setNamedItem(attribute);
}
fDocument.appendChild(fSession);
} catch (DOMException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR, exception.getLocalizedMessage(), null));
} catch (ParserConfigurationException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_IO_ERROR, exception.getLocalizedMessage(), null));
}
}
}
/**
* Creates a refactoring argument with the specified name and value.
* <p>
* If no refactoring is currently processed, this call has no effect.
* </p>
*
* @param name
* the non-empty name of the argument
* @param value
* the non-empty value of the argument
*
* @throws CoreException
* if an error occurs while creating a new argument
*/
public void createArgument(final String name, final String value) throws CoreException {
Assert.isNotNull(name);
Assert.isTrue(!"".equals(name)); //$NON-NLS-1$
Assert.isNotNull(value);
Assert.isTrue(!"".equals(value)); //$NON-NLS-1$
if (fDocument != null && fRefactoring != null && value != null) {
try {
final Attr attribute= fDocument.createAttribute(name);
attribute.setValue(value);
fRefactoring.getAttributes().setNamedItem(attribute);
} catch (DOMException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR, exception.getLocalizedMessage(), null));
}
}
}
/**
* Ends the transformation of the current refactoring.
* <p>
* If no refactoring is currently processed, this call has no effect.
* </p>
*/
public void endRefactoring() {
fRefactoring= null;
}
/**
* Ends the transformation of the current refactoring session.
* <p>
* If no refactoring session is currently processed, this call has no
* effect.
* </p>
*/
public void endSession() {
fSession= null;
}
/**
* Returns the result of the transformation process.
* <p>
* This method must only be called once during the life time of a
* transformer.
* </p>
*
* @return the object representing the refactoring session, or
* <code>null</code> if no session has been transformed
*/
public Object getResult() {
final Document document= fDocument;
fDocument= null;
return document;
}
}