blob: 90b5b0a3f0e1222c9b4314eff61f82757d3f5257 [file] [log] [blame]
nitind93023a12006-09-19 18:24:13 +00001/*******************************************************************************
2 * Copyright (c) 2006 IBM Corporation and others.
3 * 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
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *
11 *******************************************************************************/
paverydc8b3062005-10-24 20:43:42 +000012package org.eclipse.wst.sse.ui.internal.reconcile;
13
14import java.io.ByteArrayInputStream;
15import java.io.IOException;
nitind93023a12006-09-19 18:24:13 +000016import java.util.ArrayList;
17import java.util.List;
paverydc8b3062005-10-24 20:43:42 +000018
19import org.eclipse.core.runtime.Platform;
20import org.eclipse.core.runtime.content.IContentDescription;
21import org.eclipse.core.runtime.content.IContentType;
paverydc8b3062005-10-24 20:43:42 +000022import org.eclipse.jface.text.IDocument;
paverydc8b3062005-10-24 20:43:42 +000023import org.eclipse.jface.text.ITypedRegion;
nitindf3f10872007-09-03 06:36:56 +000024import org.eclipse.jface.text.Region;
paverydc8b3062005-10-24 20:43:42 +000025import org.eclipse.jface.text.reconciler.DirtyRegion;
26import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
paverydc8b3062005-10-24 20:43:42 +000027import org.eclipse.jface.text.source.ISourceViewer;
28import org.eclipse.wst.sse.ui.internal.IReleasable;
nitind93023a12006-09-19 18:24:13 +000029import org.eclipse.wst.sse.ui.internal.Logger;
paverydc8b3062005-10-24 20:43:42 +000030import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorBuilder;
31import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorMetaData;
32import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorStrategy;
nitindb0445972006-02-16 22:19:20 +000033import org.eclipse.wst.sse.ui.internal.spelling.SpellcheckStrategy;
paverydc8b3062005-10-24 20:43:42 +000034
35/**
nitindb0445972006-02-16 22:19:20 +000036 * Adds to DirtyRegionProcessor Job: - IDocumentListener - ValidatorStrategy -
37 * Text viewer(dispose, input changed) listeners. - default, spelling, and
38 * validator strategies - DirtyRegion processing logic.
paverydc8b3062005-10-24 20:43:42 +000039 */
nitindb0445972006-02-16 22:19:20 +000040public class DocumentRegionProcessor extends DirtyRegionProcessor {
paverydc8b3062005-10-24 20:43:42 +000041
nitind19a78122006-09-27 20:23:56 +000042 private static final boolean DEBUG_VALIDATORS = Boolean.TRUE.toString().equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerValidators")); //$NON-NLS-1$
nitind93023a12006-09-19 18:24:13 +000043
paverydc8b3062005-10-24 20:43:42 +000044 /**
nitindb0445972006-02-16 22:19:20 +000045 * A strategy to use the defined default Spelling service.
paverydc8b3062005-10-24 20:43:42 +000046 */
nitindb0445972006-02-16 22:19:20 +000047 private SpellcheckStrategy fSpellcheckStrategy;
paverydc8b3062005-10-24 20:43:42 +000048
paverydc8b3062005-10-24 20:43:42 +000049 /**
50 * The strategy that runs validators contributed via
51 * <code>org.eclipse.wst.sse.ui.extensions.sourcevalidation</code>
52 * extension point
53 */
54 private ValidatorStrategy fValidatorStrategy;
nitindb0445972006-02-16 22:19:20 +000055
nitinda5804e82006-03-14 00:54:11 +000056 private final String SSE_UI_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$
paverydc8b3062005-10-24 20:43:42 +000057
amywucfaee2d2006-11-21 00:28:32 +000058
nitindb0445972006-02-16 22:19:20 +000059 protected void beginProcessing() {
60 super.beginProcessing();
nitinda5804e82006-03-14 00:54:11 +000061 ValidatorStrategy validatorStrategy = getValidatorStrategy();
62 if (validatorStrategy != null) {
63 validatorStrategy.beginProcessing();
64 }
paverydc8b3062005-10-24 20:43:42 +000065 }
paverydc8b3062005-10-24 20:43:42 +000066
nitindb0445972006-02-16 22:19:20 +000067 protected void endProcessing() {
68 super.endProcessing();
nitinda5804e82006-03-14 00:54:11 +000069 ValidatorStrategy validatorStrategy = getValidatorStrategy();
70 if (validatorStrategy != null) {
71 validatorStrategy.endProcessing();
72 }
nitindb0445972006-02-16 22:19:20 +000073 }
paverydc8b3062005-10-24 20:43:42 +000074
nitindb0445972006-02-16 22:19:20 +000075 protected String getContentType(IDocument doc) {
76 if (doc == null)
77 return null;
paverydc8b3062005-10-24 20:43:42 +000078
nitindb0445972006-02-16 22:19:20 +000079 String contentTypeId = null;
paverydc8b3062005-10-24 20:43:42 +000080
nitindb0445972006-02-16 22:19:20 +000081 // pa_TODO it would be nice to be able to get filename from
82 // IDocument...
83 // because it seems that getting content type from input stream
84 // isn't all that accurate (eg. w/ a javascript file)
85
86 // IContentType ct =
87 // Platform.getContentTypeManager().findContentTypeFor("test.js");
88 IContentType ct = null;
89 try {
90 IContentDescription desc = Platform.getContentTypeManager().getDescriptionFor(new ByteArrayInputStream(doc.get().getBytes()), null, IContentDescription.ALL);
91 if (desc != null) {
92 ct = desc.getContentType();
93 if (ct != null)
94 contentTypeId = ct.getId();
paverydc8b3062005-10-24 20:43:42 +000095 }
96 }
nitindb0445972006-02-16 22:19:20 +000097 catch (IOException e) {
98 // just bail
paverydc8b3062005-10-24 20:43:42 +000099 }
nitindb0445972006-02-16 22:19:20 +0000100 return contentTypeId;
paverydc8b3062005-10-24 20:43:42 +0000101 }
paverydc8b3062005-10-24 20:43:42 +0000102
nitindb0445972006-02-16 22:19:20 +0000103 protected final StructuredTextReconcilingStrategy getSpellcheckStrategy() {
104 if (fSpellcheckStrategy == null) {
105 String contentTypeId = getContentType(getDocument());
106 if (contentTypeId != null) {
107 if (getTextViewer() instanceof ISourceViewer) {
108 ISourceViewer viewer = (ISourceViewer) getTextViewer();
109 fSpellcheckStrategy = new SpellcheckStrategy(viewer, contentTypeId);
110 fSpellcheckStrategy.setDocument(getDocument());
111 fSpellcheckStrategy.setDocumentPartitioning(getDocumentPartitioning());
paverydc8b3062005-10-24 20:43:42 +0000112 }
113 }
paverydc8b3062005-10-24 20:43:42 +0000114 }
nitindb0445972006-02-16 22:19:20 +0000115 return fSpellcheckStrategy;
paverydc8b3062005-10-24 20:43:42 +0000116 }
nitindb0445972006-02-16 22:19:20 +0000117
paverydc8b3062005-10-24 20:43:42 +0000118 /**
nitindb0445972006-02-16 22:19:20 +0000119 * @return Returns the ValidatorStrategy.
paverydc8b3062005-10-24 20:43:42 +0000120 */
nitindb0445972006-02-16 22:19:20 +0000121 protected ValidatorStrategy getValidatorStrategy() {
paverydc8b3062005-10-24 20:43:42 +0000122 if (fValidatorStrategy == null) {
123 ValidatorStrategy validatorStrategy = null;
nitindb0445972006-02-16 22:19:20 +0000124
paverydc8b3062005-10-24 20:43:42 +0000125 if (getTextViewer() instanceof ISourceViewer) {
nitindb0445972006-02-16 22:19:20 +0000126 ISourceViewer viewer = (ISourceViewer) getTextViewer();
paverydc8b3062005-10-24 20:43:42 +0000127 String contentTypeId = null;
nitindb0445972006-02-16 22:19:20 +0000128
paverydc8b3062005-10-24 20:43:42 +0000129 IDocument doc = viewer.getDocument();
130 contentTypeId = getContentType(doc);
nitindb0445972006-02-16 22:19:20 +0000131
paverydc8b3062005-10-24 20:43:42 +0000132 if (contentTypeId != null) {
paverydc8b3062005-10-24 20:43:42 +0000133 validatorStrategy = new ValidatorStrategy(viewer, contentTypeId);
134 ValidatorBuilder vBuilder = new ValidatorBuilder();
nitinda5804e82006-03-14 00:54:11 +0000135 ValidatorMetaData[] vmds = vBuilder.getValidatorMetaData(SSE_UI_ID);
nitind93023a12006-09-19 18:24:13 +0000136 List enabledValidators = new ArrayList(1);
137 /* if any "must" handle this content type, just add them */
138 boolean foundSpecificContentTypeValidators = false;
paverydc8b3062005-10-24 20:43:42 +0000139 for (int i = 0; i < vmds.length; i++) {
nitind93023a12006-09-19 18:24:13 +0000140 if (vmds[i].mustHandleContentType(contentTypeId)) {
141 if (DEBUG_VALIDATORS)
142 Logger.log(Logger.INFO, contentTypeId + " using specific validator " + vmds[i].getValidatorId()); //$NON-NLS-1$
143 foundSpecificContentTypeValidators = true;
144 enabledValidators.add(vmds[i]);
145 }
146 }
147 if (!foundSpecificContentTypeValidators) {
148 for (int i = 0; i < vmds.length; i++) {
149 if (vmds[i].canHandleContentType(contentTypeId)) {
150 if (DEBUG_VALIDATORS)
151 Logger.log(Logger.INFO, contentTypeId + " using inherited(?) validator " + vmds[i].getValidatorId()); //$NON-NLS-1$
152 enabledValidators.add(vmds[i]);
153 }
154 }
155 }
156 for (int i = 0; i < enabledValidators.size(); i++) {
157 validatorStrategy.addValidatorMetaData((ValidatorMetaData) enabledValidators.get(i));
paverydc8b3062005-10-24 20:43:42 +0000158 }
159 }
160 }
161 fValidatorStrategy = validatorStrategy;
162 }
163 return fValidatorStrategy;
164 }
165
paverydc8b3062005-10-24 20:43:42 +0000166 /**
nitindb0445972006-02-16 22:19:20 +0000167 * @param dirtyRegion
paverydc8b3062005-10-24 20:43:42 +0000168 */
nitindb0445972006-02-16 22:19:20 +0000169 protected void process(DirtyRegion dirtyRegion) {
amywucfaee2d2006-11-21 00:28:32 +0000170 if (!isInstalled() || isInRewriteSession())
nitindb0445972006-02-16 22:19:20 +0000171 return;
172
173 super.process(dirtyRegion);
174
175 // Also call the validation and spell-check strategies
176 ITypedRegion[] partitions = computePartitioning(dirtyRegion);
177
178 DirtyRegion dirty = null;
179 for (int i = 0; i < partitions.length; i++) {
nitindb0445972006-02-16 22:19:20 +0000180 // [source]validator (extension) for this partition
david_williams5ce6d6c2006-05-28 23:58:12 +0000181 if (getValidatorStrategy() != null) {
182 dirty = createDirtyRegion(partitions[i], DirtyRegion.INSERT);
nitindb0445972006-02-16 22:19:20 +0000183 getValidatorStrategy().reconcile(partitions[i], dirty);
david_williams5ce6d6c2006-05-28 23:58:12 +0000184 }
pavery1f1588d2006-02-15 20:44:54 +0000185 }
nitind93023a12006-09-19 18:24:13 +0000186
nitindb0445972006-02-16 22:19:20 +0000187 // single spell-check for everything
david_williams5ce6d6c2006-05-28 23:58:12 +0000188 if (getSpellcheckStrategy() != null) {
nitindb0445972006-02-16 22:19:20 +0000189 getSpellcheckStrategy().reconcile(dirtyRegion, dirtyRegion);
david_williams5ce6d6c2006-05-28 23:58:12 +0000190 }
paverydc8b3062005-10-24 20:43:42 +0000191 }
paverydc8b3062005-10-24 20:43:42 +0000192
nitindb0445972006-02-16 22:19:20 +0000193 public void setDocument(IDocument doc) {
194 super.setDocument(doc);
195 IReconcilingStrategy validatorStrategy = getValidatorStrategy();
196 if (validatorStrategy != null) {
197 validatorStrategy.setDocument(doc);
paverydc8b3062005-10-24 20:43:42 +0000198 }
nitind0f059552006-05-01 17:36:50 +0000199 if (fSpellcheckStrategy != null) {
200 fSpellcheckStrategy.setDocument(doc);
201 }
paverydc8b3062005-10-24 20:43:42 +0000202 }
nitindf3f10872007-09-03 06:36:56 +0000203
204 protected void setEntireDocumentDirty(IDocument document) {
205 super.setEntireDocumentDirty(document);
nitindb0445972006-02-16 22:19:20 +0000206
nitindf3f10872007-09-03 06:36:56 +0000207 // make the entire document dirty
208 // this also happens on a "save as"
209 if (document != null && isInstalled() && fLastPartitions != null && document.getLength() == 0) {
210 /**
211 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=199053
212 *
213 * Process the strategies for the last known-good partitions.
214 */
215 for (int i = 0; i < fLastPartitions.length; i++) {
216 getValidatorStrategy().reconcile(fLastPartitions[i], createDirtyRegion(fLastPartitions[i], DirtyRegion.REMOVE));
217 }
218 if (fSpellcheckStrategy != null) {
219 fSpellcheckStrategy.reconcile(new Region(0, document.getLength()));
220 }
221 }
222 }
223
nitindb0445972006-02-16 22:19:20 +0000224 /**
225 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#uninstall()
226 */
227 public void uninstall() {
228 if (isInstalled()) {
229
230 cancel();
231
nitindb0445972006-02-16 22:19:20 +0000232 IReconcilingStrategy validatorStrategy = getValidatorStrategy();
233
234 if (validatorStrategy != null) {
235 if (validatorStrategy instanceof IReleasable)
236 ((IReleasable) validatorStrategy).release();
237 }
nitind0f059552006-05-01 17:36:50 +0000238 if (fSpellcheckStrategy != null) {
239 fSpellcheckStrategy.setDocument(null);
240 }
nitindb0445972006-02-16 22:19:20 +0000241 }
242 super.uninstall();
243 }
paverydc8b3062005-10-24 20:43:42 +0000244}