001: /*******************************************************************************
002: * Copyright (c) 2000, 2004 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.examples.jspeditor;
011:
012: import java.io.IOException;
013: import java.io.Reader;
014: import java.io.StringReader;
015:
016: import org.eclipse.core.runtime.Assert;
017:
018: import org.eclipse.jface.text.BadLocationException;
019: import org.eclipse.jface.text.Document;
020: import org.eclipse.jface.text.IRegion;
021: import org.eclipse.jface.text.Position;
022: import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
023: import org.eclipse.jface.text.reconciler.DirtyRegion;
024: import org.eclipse.jface.text.reconciler.IReconcileStep;
025: import org.eclipse.jface.text.reconciler.IReconcileResult;
026: import org.eclipse.jface.text.reconciler.IReconcilableModel;
027: import org.eclipse.jface.text.source.translation.ITranslator;
028:
029: import org.eclipse.jsp.JspTranslator;
030:
031: /**
032: * This reconcile step has a JSP source document as
033: * input model and maintains a document that contains the Java
034: * source.
035: *
036: * @since 3.0
037: */
038: public class Jsp2JavaReconcileStep extends AbstractReconcileStep {
039:
040: private DocumentAdapter fModel;
041: private ITranslator fJspTranslator;
042:
043: /**
044: * Creates the last reconcile step of the pipe.
045: */
046: public Jsp2JavaReconcileStep() {
047: initialize();
048: }
049:
050: /**
051: * Creates an intermediate reconcile step which adds
052: * the given step to the pipe.
053: */
054: public Jsp2JavaReconcileStep(IReconcileStep step) {
055: super (step);
056: initialize();
057: }
058:
059: protected void initialize() {
060: fJspTranslator = new JspTranslator();
061: fJspTranslator
062: .setTagHandlerFactory(new Jsp2JavaTagHandlerFactory());
063: }
064:
065: /*
066: * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
067: */
068: protected IReconcileResult[] reconcileModel(
069: DirtyRegion dirtyRegion, IRegion subRegion) {
070: Assert.isTrue(getInputModel() instanceof DocumentAdapter,
071: "wrong model"); //$NON-NLS-1$
072:
073: System.out.println("reconciling jsp2java..."); //$NON-NLS-1$
074:
075: Reader reader = new StringReader(
076: ((DocumentAdapter) fInputModel).getDocument().get());
077: try {
078: String javaSource = fJspTranslator
079: .translate(reader, "Demo"); //$NON-NLS-1$
080: fModel = new DocumentAdapter(new Document(javaSource));
081: } catch (IOException e) {
082: e.printStackTrace();
083: return null;
084: }
085:
086: // This reconcile step does not create own results
087: return null;
088: }
089:
090: /*
091: * @see AbstractReconcileStep#getModel()
092: */
093: public IReconcilableModel getModel() {
094: return fModel;
095: }
096:
097: /*
098: * @see AbstractReconcileStep#convertToInputModel(IReconcileResult[])
099: */
100: protected IReconcileResult[] convertToInputModel(
101: IReconcileResult[] inputResults) {
102:
103: if (inputResults == null)
104: return null;
105:
106: // the "only" thing we need to do is to adapt the positions
107: int[] smap = fJspTranslator.getLineMapping();
108:
109: for (int i = 0; i < inputResults.length; i++) {
110:
111: if (isCanceled())
112: return null;
113:
114: if (!(inputResults[i] instanceof AnnotationAdapter))
115: continue;
116:
117: AnnotationAdapter result = (AnnotationAdapter) inputResults[i];
118: Position pos = result.getPosition();
119: int javaLine;
120: try {
121: javaLine = fModel.getDocument().getLineOfOffset(
122: pos.offset);
123:
124: // Adjust offset to be relative to line beginning
125: pos.offset -= fModel.getDocument().getLineOffset(
126: javaLine);
127: int relativeLineOffsetInJava = pos.offset;
128:
129: int jspLine = smap[javaLine + 1]; // document is 0-based, smap is 1-based
130:
131: // Add Jsp line offset
132: pos.offset += ((DocumentAdapter) getInputModel())
133: .getDocument().getLineOffset(jspLine - 1); // document is 0-based, smap is 1-based
134:
135: String jspLineStr = ((DocumentAdapter) getInputModel())
136: .getDocument().get(
137: ((DocumentAdapter) getInputModel())
138: .getDocument().getLineOffset(
139: jspLine - 1),
140: ((DocumentAdapter) getInputModel())
141: .getDocument().getLineLength(
142: jspLine - 1));
143:
144: // XXX: Once partitioner is in place the partition can be used to ease section detection
145: int offsetInLine = fJspTranslator
146: .backTranslateOffsetInLine(jspLineStr, null,
147: relativeLineOffsetInJava, null);
148: if (offsetInLine > 0)
149: pos.offset += offsetInLine;
150:
151: } catch (BadLocationException e) {
152: e.printStackTrace();
153: }
154: }
155: return inputResults;
156: }
157: }
|