public void connect(IDocument document) { fDocument = document; // special checks to see source validation should really execute IFile file = null; IStructuredModel model = null; try { model = StructuredModelManager.getModelManager().getExistingModelForRead(document); if (model != null) { String baseLocation = model.getBaseLocation(); // The baseLocation may be a path on disk or relative to the // workspace root. Don't translate on-disk paths to // in-workspace resources. IPath basePath = new Path(baseLocation); if (basePath.segmentCount() > 1) { file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath); /* * If the IFile doesn't exist, make sure it's not returned */ if (!file.exists()) file = null; } } } finally { if (model != null) { model.releaseFromRead(); } } fEnableSourceValidation = (file != null && isBatchValidatorPreferenceEnabled(file) && shouldValidate(file) && fragmentCheck(file)); }
private void onDescriptorsChanged() { IStructuredModel model = getModelForRead(); if (model != null) { try { Node node = getManifestXmlNode(getXmlDocument(model)); mUiManifestNode.reloadFromXmlNode(node); } finally { model.releaseFromRead(); } } if (mOverviewPage != null) { mOverviewPage.refreshUiApplicationNode(); } if (mAppPage != null) { mAppPage.refreshUiApplicationNode(); } if (mPermissionPage != null) { mPermissionPage.refreshUiNode(); } if (mInstrumentationPage != null) { mInstrumentationPage.refreshUiNode(); } }
/** * Method validateEdit. * * @param file org.eclipse.core.resources.IFile * @param context org.eclipse.swt.widgets.Shell * @return IStatus */ private static IStatus validateEdit(IFile file, Shell context) { if (file == null || !file.exists()) return STATUS_ERROR; if (!(file.isReadOnly())) return STATUS_OK; IPath location = file.getLocation(); final long beforeModifiedFromJavaIO = (location != null) ? location.toFile().lastModified() : IResource.NULL_STAMP; final long beforeModifiedFromIFile = file.getModificationStamp(); IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, context); if (!status.isOK()) return status; final long afterModifiedFromJavaIO = (location != null) ? location.toFile().lastModified() : IResource.NULL_STAMP; final long afterModifiedFromIFile = file.getModificationStamp(); if (beforeModifiedFromJavaIO != afterModifiedFromJavaIO || beforeModifiedFromIFile != afterModifiedFromIFile) { IModelManager manager = StructuredModelManager.getModelManager(); IStructuredModel model = manager.getExistingModelForRead(file); if (model != null) { if (!model.isDirty()) { try { file.refreshLocal(IResource.DEPTH_ONE, null); } catch (CoreException e) { return STATUS_ERROR; } finally { model.releaseFromRead(); } } else { model.releaseFromRead(); } } } if ((beforeModifiedFromJavaIO != afterModifiedFromJavaIO) || (beforeModifiedFromIFile != afterModifiedFromIFile)) { // the file is replaced. Modification cannot be // applied. return STATUS_ERROR; } return STATUS_OK; }
protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) { IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument); IndexedRegion indexedRegion = null; try { if (sModel != null) indexedRegion = sModel.getIndexedRegion(sdRegion.getStart()); } finally { if (sModel != null) sModel.releaseFromRead(); } return indexedRegion; }
private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) { IModelManager modelManager = StructuredModelManager.getModelManager(); IStructuredModel model = null; try { model = modelManager.getExistingModelForRead(file); if (model == null) { model = modelManager.getModelForRead(file); } if (model != null) { IStructuredDocument document = model.getStructuredDocument(); if (model instanceof IDOMModel) { IDOMModel domModel = (IDOMModel) model; Element root = domModel.getDocument().getDocumentElement(); if (root != null) { List<TextEdit> edits = new ArrayList<TextEdit>(); if (isManifest) { addManifestReplacements(edits, root, document); } else { addLayoutReplacements(edits, root, document); } if (!edits.isEmpty()) { MultiTextEdit rootEdit = new MultiTextEdit(); rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()])); TextFileChange change = new TextFileChange(file.getName(), file); change.setTextType(EXT_XML); change.setEdit(rootEdit); changes.add(change); } } } else { return false; } } return true; } catch (IOException e) { AdtPlugin.log(e, null); } catch (CoreException e) { AdtPlugin.log(e, null); } finally { if (model != null) { model.releaseFromRead(); } } return false; }
/** * Returns the content type of document * * @param document - assumes document is not null * @return String content type of given document */ private String getContentType() { String type = null; IModelManager mgr = StructuredModelManager.getModelManager(); IStructuredModel model = null; try { model = mgr.getExistingModelForRead(document); if (model != null) { type = model.getContentTypeIdentifier(); } } finally { if (model != null) { model.releaseFromRead(); } } return type; }
public static IProject getProject(IDocument document) { IStructuredModel model = null; try { model = StructuredModelManager.getModelManager().getExistingModelForRead(document); if (model != null) { String baselocation = model.getBaseLocation(); if (baselocation != null) { // copied from JSPTranslationAdapter#getJavaProject IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IPath filePath = new Path(baselocation); if (filePath.segmentCount() > 0) { return root.getProject(filePath.segment(0)); } } } return null; } finally { if (model != null) model.releaseFromRead(); } }
/** * Returns the closest IndexedRegion for the offset and viewer allowing for differences between * viewer offsets and model positions. note: this method returns an IndexedRegion for read only * * @param viewer the viewer whose document is used to compute the proposals * @param documentOffset an offset within the document for which completions should be computed * @return an IndexedRegion */ public static IndexedRegion getNodeAt(ITextViewer viewer, int documentOffset) { if (viewer == null) return null; IndexedRegion node = null; IModelManager mm = StructuredModelManager.getModelManager(); IStructuredModel model = null; if (mm != null) model = mm.getExistingModelForRead(viewer.getDocument()); try { if (model != null) { int lastOffset = documentOffset; node = model.getIndexedRegion(documentOffset); while (node == null && lastOffset >= 0) { lastOffset--; node = model.getIndexedRegion(lastOffset); } } } finally { if (model != null) model.releaseFromRead(); } return node; }
/** * Validate one file. It's assumed that the file has JSP content type. * * @param f * @param reporter */ protected void validateFile(IFile f, IReporter reporter) { if (JsValidator.DEBUG) { Logger.log(Logger.INFO, getClass().getName() + " validating: " + f); // $NON-NLS-1$ } IStructuredModel model = null; try { // get jsp model, get tranlsation model = StructuredModelManager.getModelManager().getModelForRead(f); if (!reporter.isCancelled() && model != null) { // get DOM model then translation // WorkbenchReporter.removeAllMessages(f.getProject(), jsdtValidator, f.toString()); // reporter.removeAllMessages(fMessageOriginator, f); performValidation(f, reporter, model, false); } } catch (IOException e) { Logger.logException(e); } catch (CoreException e) { Logger.logException(e); } finally { if (model != null) { model.releaseFromRead(); } } }
/** * originally copied from org.eclipse.wst.xml.ui.internal.hyperlink.XMLHyperlinkDetector this * method grabs the IDOMModel for the IDocument, performs the passed operation on the node at the * offset and then releases the IDOMModel operation's Node value is also an instance of * IndexedRegion * * @param offset */ public static void performOnCurrentElement( IDocument document, int offset, NodeOperation<Node> operation) { assert document != null; assert operation != null; // get the current node at the offset (returns either: element, // doctype, text) IStructuredModel sModel = null; try { sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document); if (sModel != null) { IndexedRegion inode = sModel.getIndexedRegion(offset); if (inode == null) { inode = sModel.getIndexedRegion(offset - 1); } if (inode instanceof Node) { operation.process((Node) inode, sModel.getStructuredDocument()); } } } finally { if (sModel != null) { sModel.releaseFromRead(); } } }
/** * This validate call is for the ISourceValidator partial document validation approach * * @param dirtyRegion * @param helper * @param reporter * @see org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator */ public void validate(IRegion dirtyRegion, IValidationContext helper, IReporter reporter) { if (helper == null || fDocument == null || !fEnableSourceValidation) return; if ((reporter != null) && (reporter.isCancelled() == true)) { throw new OperationCanceledException(); } IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument); if (model == null) return; // error try { IDOMDocument document = null; if (model instanceof IDOMModel) { document = ((IDOMModel) model).getDocument(); } if (document == null || !hasHTMLFeature(document)) return; // ignore ITextFileBuffer fb = FileBufferModelManager.getInstance().getBuffer(fDocument); if (fb == null) return; IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(fb.getLocation()); if (file == null || !file.exists()) return; // this will be the wrong region if it's Text (instead of Element) // we don't know how to validate Text IndexedRegion ir = getCoveringNode(dirtyRegion); // model.getIndexedRegion(dirtyRegion.getOffset()); if (ir instanceof Text) { while (ir != null && ir instanceof Text) { // it's assumed that this gets the IndexedRegion to // the right of the end offset ir = model.getIndexedRegion(ir.getEndOffset()); } } if (ir instanceof INodeNotifier) { INodeAdapterFactory factory = HTMLValidationAdapterFactory.getInstance(); ValidationAdapter adapter = (ValidationAdapter) factory.adapt((INodeNotifier) ir); if (adapter == null) return; // error if (reporter != null) { HTMLValidationReporter rep = null; rep = getReporter(reporter, file, (IDOMModel) model); rep.clear(); adapter.setReporter(rep); Message mess = new LocalizedMessage( IMessage.LOW_SEVERITY, file.getFullPath().toString().substring(1)); reporter.displaySubtask(this, mess); } adapter.validate(ir); } } finally { if (model != null) model.releaseFromRead(); } }
@Override protected List<Change> computeChanges(IProgressMonitor monitor) { String name = getViewClass(mTypeFqcn); IFile file = mDelegate.getEditor().getInputFile(); List<Change> changes = new ArrayList<Change>(); if (file == null) { return changes; } TextFileChange change = new TextFileChange(file.getName(), file); MultiTextEdit rootEdit = new MultiTextEdit(); change.setEdit(rootEdit); change.setTextType(EXT_XML); changes.add(change); for (Element element : getElements()) { IndexedRegion region = getRegion(element); String text = getText(region.getStartOffset(), region.getEndOffset()); String oldName = element.getNodeName(); int open = text.indexOf(oldName); int close = text.lastIndexOf(oldName); if (element instanceof ElementImpl && ((ElementImpl) element).isEmptyTag()) { close = -1; } if (open != -1) { int oldLength = oldName.length(); rootEdit.addChild(new ReplaceEdit(region.getStartOffset() + open, oldLength, name)); } if (close != -1 && close != open) { int oldLength = oldName.length(); rootEdit.addChild(new ReplaceEdit(region.getStartOffset() + close, oldLength, name)); } // Change tag type String oldId = getId(element); String newId = ensureIdMatchesType(element, mTypeFqcn, rootEdit); // Update any layout references to the old id with the new id if (oldId != null && newId != null) { IStructuredModel model = mDelegate.getEditor().getModelForRead(); try { IStructuredDocument doc = model.getStructuredDocument(); if (doc != null) { IndexedRegion range = getRegion(element); int skipStart = range.getStartOffset(); int skipEnd = range.getEndOffset(); List<TextEdit> replaceIds = replaceIds(getAndroidNamespacePrefix(), doc, skipStart, skipEnd, oldId, newId); for (TextEdit edit : replaceIds) { rootEdit.addChild(edit); } } } finally { model.releaseFromRead(); } } // Strip out attributes that no longer make sense removeUndefinedAttrs(rootEdit, element); } return changes; }
public void customizeDocumentCommand(IDocument document, DocumentCommand c) { if (!isSmartInsertMode()) { return; } if (!(document instanceof IStructuredDocument)) { // This shouldn't happen unless this strategy is used on an invalid document return; } IStructuredDocument doc = (IStructuredDocument) document; // Handle newlines/indentation if (c.length == 0 && c.text != null && TextUtilities.endsWith(doc.getLegalLineDelimiters(), c.text) != -1) { IModelManager modelManager = StructuredModelManager.getModelManager(); IStructuredModel model = modelManager.getModelForRead(doc); if (model != null) { try { final int offset = c.offset; int lineStart = findLineStart(doc, offset); int textStart = findTextStart(doc, lineStart, offset); IStructuredDocumentRegion region = doc.getRegionAtCharacterOffset(textStart); if (region != null && region.getType().equals(XML_TAG_NAME)) { Pair<Integer, Integer> balance = getBalance(doc, textStart, offset); int tagBalance = balance.getFirst(); int bracketBalance = balance.getSecond(); String lineIndent = ""; // $NON-NLS-1$ if (textStart > lineStart) { lineIndent = doc.get(lineStart, textStart - lineStart); } // We only care if tag or bracket balance is greater than 0; // we never *dedent* on negative balances boolean addIndent = false; if (bracketBalance < 0) { // Handle // <foo // ></foo>^ // and // <foo // />^ ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); if (left != null && (left.getType().equals(XML_TAG_CLOSE) || left.getType().equals(XML_EMPTY_TAG_CLOSE))) { // Find the corresponding open tag... // The org.eclipse.wst.xml.ui.gotoMatchingTag frequently // doesn't work, it just says "No matching brace found" // (or I would use that here). int targetBalance = 0; ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (right != null && right.getType().equals(XML_END_TAG_OPEN)) { targetBalance = -1; } int openTag = AndroidXmlCharacterMatcher.findTagBackwards(doc, offset, targetBalance); if (openTag != -1) { // Look up the indentation of the given line lineIndent = AndroidXmlEditor.getIndentAtOffset(doc, openTag); } } } else if (tagBalance > 0 || bracketBalance > 0) { // Add indentation addIndent = true; } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); if (addIndent) { sb.append(oneIndentUnit); } // Handle // <foo>^</foo> // turning into // <foo> // ^ // </foo> ITextRegion left = getRegionAt(doc, offset, true /*biasLeft*/); ITextRegion right = getRegionAt(doc, offset, false /*biasLeft*/); if (left != null && right != null && left.getType().equals(XML_TAG_CLOSE) && right.getType().equals(XML_END_TAG_OPEN)) { // Move end tag if (tagBalance > 0 && bracketBalance < 0) { sb.append(oneIndentUnit); } c.caretOffset = offset + sb.length(); c.shiftsCaret = false; sb.append(TextUtilities.getDefaultLineDelimiter(doc)); sb.append(lineIndent); } c.text = sb.toString(); } else if (region != null && region.getType().equals(XML_CONTENT)) { // Indenting in text content. If you're in the middle of editing // text, just copy the current line indentation. // However, if you're editing in leading whitespace (e.g. you press // newline on a blank line following say an element) then figure // out the indentation as if the newline had been pressed at the // end of the element, and insert that amount of indentation. // In this case we need to also make sure to subtract any existing // whitespace on the current line such that if we have // // <foo> // ^ <bar/> // </foo> // // you end up with // // <foo> // // ^<bar/> // </foo> // String text = region.getText(); int regionStart = region.getStartOffset(); int delta = offset - regionStart; boolean inWhitespacePrefix = true; for (int i = 0, n = Math.min(delta, text.length()); i < n; i++) { char ch = text.charAt(i); if (!Character.isWhitespace(ch)) { inWhitespacePrefix = false; break; } } if (inWhitespacePrefix) { IStructuredDocumentRegion previous = region.getPrevious(); if (previous != null && previous.getType() == XML_TAG_NAME) { ITextRegionList subRegions = previous.getRegions(); ITextRegion last = subRegions.get(subRegions.size() - 1); if (last.getType() == XML_TAG_CLOSE || last.getType() == XML_EMPTY_TAG_CLOSE) { int begin = AndroidXmlCharacterMatcher.findTagBackwards( doc, previous.getStartOffset() + last.getStart(), 0); int prevLineStart = findLineStart(doc, begin); int prevTextStart = findTextStart(doc, prevLineStart, begin); String lineIndent = ""; // $NON-NLS-1$ if (prevTextStart > prevLineStart) { lineIndent = doc.get(prevLineStart, prevTextStart - prevLineStart); } StringBuilder sb = new StringBuilder(c.text); sb.append(lineIndent); String oneIndentUnit = XmlFormatPreferences.create().getOneIndentUnit(); // See if there is whitespace on the insert line that // we should also remove for (int i = delta, n = text.length(); i < n; i++) { char ch = text.charAt(i); if (ch == ' ') { c.length++; } else { break; } } boolean onClosingTagLine = false; if (text.indexOf('\n', delta) == -1) { IStructuredDocumentRegion next = region.getNext(); if (next != null && next.getType() == XML_TAG_NAME) { String nextType = next.getRegions().get(0).getType(); if (nextType == XML_END_TAG_OPEN) { onClosingTagLine = true; } } } boolean addIndent = (last.getType() == XML_TAG_CLOSE) && !onClosingTagLine; if (addIndent) { sb.append(oneIndentUnit); } c.text = sb.toString(); return; } } } copyPreviousLineIndentation(doc, c); } else { copyPreviousLineIndentation(doc, c); } } catch (BadLocationException e) { AdtPlugin.log(e, null); } finally { model.releaseFromRead(); } } } }
/** Filters out every {@link IFile} which is has unknown root elements in its XML content. */ @Override protected Set<IFile> filterMatchingFiles(Set<IFile> files) { // if project is a java project remove bin dirs from the list Set<String> outputDirectories = new HashSet<String>(); IJavaProject javaProject = JdtUtils.getJavaProject(project); if (javaProject != null) { try { // add default output directory outputDirectories.add(javaProject.getOutputLocation().toString()); // add source folder specific output directories for (IClasspathEntry entry : javaProject.getRawClasspath()) { if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE && entry.getOutputLocation() != null) { outputDirectories.add(entry.getOutputLocation().toString()); } } } catch (JavaModelException e) { BeansCorePlugin.log(e); } } Set<IFile> detectedFiles = new LinkedHashSet<IFile>(); for (IFile file : files) { boolean skip = false; // first check if the file sits in an output directory String path = file.getFullPath().toString(); for (String outputDirectory : outputDirectories) { if (path.startsWith(outputDirectory)) { skip = true; } } if (skip) { continue; } // check if the file is known Spring xml file IStructuredModel model = null; try { try { model = StructuredModelManager.getModelManager().getExistingModelForRead(file); } catch (RuntimeException e) { // sometimes WTP throws a NPE in concurrency situations } if (model == null) { model = StructuredModelManager.getModelManager().getModelForRead(file); } if (model != null) { IDOMDocument document = ((DOMModelImpl) model).getDocument(); if (document != null && document.getDocumentElement() != null) { String namespaceUri = document.getDocumentElement().getNamespaceURI(); if (applyNamespaceFilter(file, namespaceUri)) { detectedFiles.add(file); } } } } catch (IOException e) { BeansCorePlugin.log(e); } catch (CoreException e) { BeansCorePlugin.log(e); } finally { if (model != null) { model.releaseFromRead(); } } } return detectedFiles; }