blob: bd8b0b781357ae5381bad3f52a0474540469be63 [file] [log] [blame]
david_williamscfdb2cd2004-11-11 08:37:49 +00001/*******************************************************************************
amywuecebb042007-04-10 20:07:35 +00002 * Copyright (c) 2001, 2006 IBM Corporation and others.
david_williamscfdb2cd2004-11-11 08:37:49 +00003 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
amywuecebb042007-04-10 20:07:35 +00007 *
david_williamscfdb2cd2004-11-11 08:37:49 +00008 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Jens Lukowski/Innoopract - initial renaming/restructuring
11 *
12 *******************************************************************************/
13package org.eclipse.wst.sse.ui.internal.reconcile;
14
15import java.util.ArrayList;
16import java.util.Arrays;
17import java.util.HashSet;
david_williamscfdb2cd2004-11-11 08:37:49 +000018import java.util.List;
19
pavery46c93e72005-02-08 16:07:33 +000020import org.eclipse.core.runtime.Platform;
paveryf4a08b32005-02-02 21:39:25 +000021import org.eclipse.jface.text.BadLocationException;
david_williamscfdb2cd2004-11-11 08:37:49 +000022import org.eclipse.jface.text.IDocument;
david_williamscfdb2cd2004-11-11 08:37:49 +000023import org.eclipse.jface.text.IRegion;
24import org.eclipse.jface.text.ITypedRegion;
paveryf4a08b32005-02-02 21:39:25 +000025import org.eclipse.jface.text.TextUtilities;
david_williamscfdb2cd2004-11-11 08:37:49 +000026import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
27import org.eclipse.jface.text.reconciler.DirtyRegion;
28import org.eclipse.jface.text.reconciler.IReconcilableModel;
29import org.eclipse.jface.text.reconciler.IReconcileResult;
david_williams4ad020f2005-04-18 08:00:30 +000030import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
31import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
david_williams4ad020f2005-04-18 08:00:30 +000032import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
paveryb0f98c52006-02-13 20:19:39 +000033import org.eclipse.wst.sse.core.text.IStructuredPartitions;
pavery0f11a862005-03-29 21:14:36 +000034import org.eclipse.wst.sse.ui.internal.IReleasable;
paveryf4a08b32005-02-02 21:39:25 +000035import org.eclipse.wst.sse.ui.internal.Logger;
david_williamscfdb2cd2004-11-11 08:37:49 +000036
37
38/**
39 * ReconcileStep that knows about the annotation that it adds to the
40 * AnnotationModel. It knows how to create an annotation key (for smart
41 * removal later) It knows the partition types on which it can operate. It
42 * knows the scope on which it operates (for short circuiting) It knows if the
43 * Reconciler is reconciling the entire document.
44 *
45 * Clients must subclass this class.
46 *
47 * @author pavery
48 */
paveryf4a08b32005-02-02 21:39:25 +000049public abstract class StructuredReconcileStep extends AbstractReconcileStep implements IReleasable {
david_williamscfdb2cd2004-11-11 08:37:49 +000050
david_williamsd6ee0692005-02-23 16:38:05 +000051 /** debug flag */
52 protected static final boolean DEBUG;
53 static {
54 String value = Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerjob"); //$NON-NLS-1$
55 DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
56 }
57
david_williamscfdb2cd2004-11-11 08:37:49 +000058 protected final IReconcileResult[] EMPTY_RECONCILE_RESULT_SET = new IReconcileResult[0];
pavery3b75d5d2005-11-10 02:27:12 +000059
david_williamscfdb2cd2004-11-11 08:37:49 +000060 /**
61 * It's possible for a partial step to get called on the same area twice
62 * (as w/ a full document reconcile) this list keeps track of area already
63 * covered. Should be reset() after the "batch" of reconciling is
64 * finished.
65 */
david_williamscfdb2cd2004-11-11 08:37:49 +000066 private HashSet fPartitionTypes = null;
67
68 public StructuredReconcileStep() {
69 super();
70 fPartitionTypes = new HashSet();
david_williamscfdb2cd2004-11-11 08:37:49 +000071 }
72
pavery55ae4472005-02-16 23:00:16 +000073 public ReconcileAnnotationKey createKey(IStructuredDocumentRegion sdRegion, int scope) {
david_williamsd6ee0692005-02-23 16:38:05 +000074
75 ITypedRegion tr = getPartition(sdRegion);
paveryb0f98c52006-02-13 20:19:39 +000076 String partitionType = (tr != null) ? tr.getType() : IStructuredPartitions.UNKNOWN_PARTITION;
david_williamscfdb2cd2004-11-11 08:37:49 +000077 return createKey(partitionType, scope);
78 }
79
david_williamsd6ee0692005-02-23 16:38:05 +000080 /**
81 * @param sdRegion
82 * @return
83 */
paveryb0763c02005-10-17 15:55:28 +000084 protected ITypedRegion getPartition(IStructuredDocumentRegion sdRegion) {
david_williamsd6ee0692005-02-23 16:38:05 +000085 ITypedRegion tr = null;
86 if (!sdRegion.isDeleted())
87 tr = getPartition(sdRegion.getParentDocument(), sdRegion.getStartOffset());
88 return tr;
89 }
90
91 private ITypedRegion getPartition(IDocument doc, int offset) {
92 ITypedRegion tr = null;
93 // not sure why document would ever be null, but put in this
94 // guard for
95 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=86069
96 if (doc != null) {
97 try {
pavery40dd89e2005-04-01 21:09:29 +000098 tr = TextUtilities.getPartition(doc, IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING, offset, false);
david_williamsd6ee0692005-02-23 16:38:05 +000099 } catch (BadLocationException e) {
100 if (DEBUG)
david_williamsb9da93e2005-04-13 02:38:05 +0000101 Logger.logException("problem getting partition at: " + offset, e); //$NON-NLS-1$
david_williamsd6ee0692005-02-23 16:38:05 +0000102 }
103 }
104 return tr;
105 }
106
david_williamscfdb2cd2004-11-11 08:37:49 +0000107 /**
108 * Clients should use this method to create annotation keys as it
109 * registers the key for removal later.
110 *
111 * @param partitionType
112 * @param scope
113 * @return
114 */
pavery55ae4472005-02-16 23:00:16 +0000115 public ReconcileAnnotationKey createKey(String partitionType, int scope) {
david_williamscfdb2cd2004-11-11 08:37:49 +0000116 fPartitionTypes.add(partitionType);
117 return new ReconcileAnnotationKey(this, partitionType, scope);
118 }
119
120 protected IDocument getDocument() {
121 IDocument doc = null;
122 IReconcilableModel rModel = getModel();
123 if (rModel instanceof DocumentAdapter) {
124 doc = ((DocumentAdapter) rModel).getDocument();
125 }
126 return doc;
127 }
128
david_williamscfdb2cd2004-11-11 08:37:49 +0000129 public IReconcilableModel getModel() {
130 return getInputModel();
131 }
132
paveryf4a08b32005-02-02 21:39:25 +0000133 public String getPartitionType(IDocument doc, int offset) {
david_williamsd6ee0692005-02-23 16:38:05 +0000134 ITypedRegion tr = getPartition(doc, offset);
paveryb0f98c52006-02-13 20:19:39 +0000135 return (tr != null) ? tr.getType() : IStructuredPartitions.UNKNOWN_PARTITION;
david_williamscfdb2cd2004-11-11 08:37:49 +0000136 }
137
138 public String[] getPartitionTypes() {
139 // using hash set to automatically get rid of dupes
140 HashSet tempResults = new HashSet();
141 // add these partition types
142 tempResults.addAll(fPartitionTypes);
david_williamscfdb2cd2004-11-11 08:37:49 +0000143 return (String[]) tempResults.toArray(new String[tempResults.size()]);
144 }
145
david_williamscfdb2cd2004-11-11 08:37:49 +0000146 protected IStructuredDocument getStructuredDocument() {
147 IStructuredDocument sDoc = null;
148 IDocument doc = getDocument();
149 if (doc instanceof IStructuredDocument)
150 sDoc = (IStructuredDocument) getDocument();
151 return sDoc;
152 }
153
154 /**
david_williamscfdb2cd2004-11-11 08:37:49 +0000155 * Removes duplicates.
156 *
157 * @param results1
158 * @param results2
159 * @return
160 */
161 protected IReconcileResult[] merge(IReconcileResult[] results1, IReconcileResult[] results2) {
162 if (results1 == null)
163 return results2;
164 if (results2 == null)
165 return results1;
166
167 List results = new ArrayList();
168 results.addAll(Arrays.asList(results1));
169 for (int i = 0; i < results2.length; i++) {
paveryf4a08b32005-02-02 21:39:25 +0000170 results.add(results2[i]);
david_williamscfdb2cd2004-11-11 08:37:49 +0000171 }
david_williamscfdb2cd2004-11-11 08:37:49 +0000172 return (IReconcileResult[]) results.toArray(new IReconcileResult[results.size()]);
173 }
174
david_williamscfdb2cd2004-11-11 08:37:49 +0000175 /*
176 * (non-Javadoc)
177 *
178 * @see org.eclipse.jface.text.reconciler.AbstractReconcileStep#reconcileModel(org.eclipse.jface.text.reconciler.DirtyRegion,
179 * org.eclipse.jface.text.IRegion)
180 */
181 protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion) {
182 return EMPTY_RECONCILE_RESULT_SET;
183 }
184
185 /**
186 * Release resources used by the step here as needed. Be sure to call
187 * super.release() when you override this method as to propagate the
188 * release through all steps.
189 */
190 public void release() {
pavery3b75d5d2005-11-10 02:27:12 +0000191 //
david_williamscfdb2cd2004-11-11 08:37:49 +0000192 }
amywuecebb042007-04-10 20:07:35 +0000193}