blob: 1b49384c7becef10d598273dffcf71beff97c1a0 [file] [log] [blame]
package org.eclipse.wst.jsdt.web.ui.internal.format;
import java.util.LinkedList;
import java.util.Map;
import java.util.Vector;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IDocumentPartitioningListener;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TypedPosition;
import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IFormattingContext;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.jsdt.core.ICompilationUnit;
import org.eclipse.wst.jsdt.core.IJavaProject;
import org.eclipse.wst.jsdt.core.JavaCore;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.core.formatter.CodeFormatter;
import org.eclipse.wst.jsdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.wst.jsdt.internal.formatter.DefaultCodeFormatter;
import org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslationUtil;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.rules.StructuredTextPartitioner;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
public class FormattingStrategyJSPJava extends ContextBasedFormattingStrategy{
/** Documents to be formatted by this strategy */
private final LinkedList fDocuments= new LinkedList();
/** Partitions to be formatted by this strategy */
private final LinkedList fPartitions= new LinkedList();
private static final int regionStartIndentLevel=1;
private int startIndentLevel;
/**
* Creates a new java formatting strategy.
*/
public FormattingStrategyJSPJava() {
super();
}
private class partitionerAttachedChangeListener implements IDocumentPartitioningListener{
private IDocument attachedDoc;
partitionerAttachedChangeListener(IDocument attachedDoc){
this.attachedDoc=attachedDoc;
}
public void documentPartitioningChanged(IDocument document) {
if (document==attachedDoc && document instanceof IDocumentExtension3) {
IDocumentExtension3 extension3= (IDocumentExtension3) document;
String[] partitionings= extension3.getPartitionings();
Vector partitioners = new Vector();
for (int i= 0; i < partitionings.length; i++) {
IDocumentPartitioner partitioner= extension3.getDocumentPartitioner(partitionings[i]);
if (partitioner instanceof StructuredTextPartitioner) {
IDOMModel xmlModel = null;
try {
xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(document);
xmlModel.reinit();
}catch(Exception e){
System.out.println("Exception in adapter for model re-init"+e);
} finally {
if (xmlModel != null) {
xmlModel.releaseFromRead();
}
}
document.removeDocumentPartitioningListener(this);
}
}
}
}
}
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#format()
*/
public void format() {
super.format();
final IStructuredDocument document= (IStructuredDocument)fDocuments.removeFirst();
final TypedPosition partition= (TypedPosition)fPartitions.removeFirst();
if (document != null) {
try {
JSPTranslationUtil translationUtil = new JSPTranslationUtil(document);
ICompilationUnit cu = translationUtil.getCompilationUnit();
if (cu != null) {
String cuSource = cu.getSource();
int javaStart = translationUtil.getTranslation().getJavaOffset(partition.getOffset());
int javaLength = partition.getLength();
TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, cuSource, javaStart, javaLength, startIndentLevel, TextUtilities.getDefaultLineDelimiter(document), getPreferences());
IDocument doc = translationUtil.getTranslation().getJavaDocument();
edit.apply(doc);
String replaceText = TextUtilities.getDefaultLineDelimiter(document) + getIndentationString(getPreferences(),startIndentLevel) + (doc.get(edit.getOffset(), edit.getLength())).trim() + TextUtilities.getDefaultLineDelimiter(document);
/* this is necisary since SSE disconnects document partitioners.. Because of that, the
* replaced regions are considered 'partitionless' when the linestyle provider trys to
* color them.
*
*/
document.replaceText(document, partition.getOffset(), partition.getLength(), replaceText);
document.addDocumentPartitioningListener(new partitionerAttachedChangeListener(document));
}
}catch(BadLocationException e){
}catch(JavaModelException e){
}
}
}
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
*/
public void formatterStarts(final IFormattingContext context) {
fPartitions.addLast(context.getProperty(FormattingContextProperties.CONTEXT_PARTITION));
fDocuments.addLast(context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM));
startIndentLevel = regionStartIndentLevel + 0;
Map projectOptions = (Map)context.getProperty(FormattingContextProperties.CONTEXT_PREFERENCES);
if(projectOptions==null ){
IDocument doc = (IDocument)context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM);
context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, getProjectOptions(doc));
}
super.formatterStarts(context);
}
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
*/
public void formatterStops() {
super.formatterStops();
fPartitions.clear();
fDocuments.clear();
startIndentLevel=0;
}
public String getIndentationString(Map options, int indentationLevel){
DefaultCodeFormatter formatter = new DefaultCodeFormatter(options);
return formatter.createIndentationString(indentationLevel);
}
private Map getProjectOptions(IDocument baseDocument){
IJavaProject javaProject = null;
IDOMModel xmlModel = null;
Map options = null;
try {
xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(baseDocument);
String baseLocation = xmlModel.getBaseLocation();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IPath filePath = new Path(baseLocation);
IProject project = null;
if (filePath.segmentCount() > 0) {
project = root.getProject(filePath.segment(0));
}
if(project!=null)
javaProject = JavaCore.create(project);
} finally {
if (xmlModel != null) {
xmlModel.releaseFromRead();
}
}
if(javaProject!=null){
options = javaProject.getOptions(true);
}
return options;
}
private Map getNodeFromRegion(IDocument baseDocument){
IJavaProject javaProject = null;
IDOMModel xmlModel = null;
Map options = null;
try {
xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(baseDocument);
} finally {
if (xmlModel != null) {
xmlModel.releaseFromRead();
}
}
if(javaProject!=null){
options = javaProject.getOptions(true);
}
return options;
}
}