| /******************************************************************************* |
| * Copyright (c) 2001, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.xsd.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.EventObject; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.emf.common.command.BasicCommandStack; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.command.CommandStackListener; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IFileEditorInput; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.editors.text.JavaFileEditorInput; |
| import org.eclipse.ui.views.properties.PropertySheet; |
| import org.eclipse.wst.common.ui.properties.ITabbedPropertySheetPageContributor; |
| import org.eclipse.wst.sse.core.INodeAdapter; |
| import org.eclipse.wst.sse.core.INodeNotifier; |
| import org.eclipse.wst.sse.core.IStructuredModel; |
| import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException; |
| import org.eclipse.wst.sse.core.internal.SSECorePlugin; |
| import org.eclipse.wst.sse.core.undo.IStructuredTextUndoManager; |
| import org.eclipse.wst.sse.ui.StructuredTextEditor; |
| import org.eclipse.wst.xml.core.document.XMLModel; |
| import org.eclipse.wst.xml.core.internal.document.XMLModelImpl; |
| import org.eclipse.wst.xsd.ui.internal.graph.XSDGraphViewer; |
| //import org.eclipse.wst.xsd.ui.internal.graph.model.XSDModelAdapterFactory; |
| import org.eclipse.wst.xsd.ui.internal.util.OpenOnSelectionHelper; |
| import org.eclipse.wst.xsd.ui.internal.util.XSDDOMHelper; |
| import org.eclipse.xsd.XSDConcreteComponent; |
| import org.eclipse.xsd.XSDPackage; |
| import org.eclipse.xsd.XSDSchema; |
| import org.eclipse.xsd.impl.XSDSchemaImpl; |
| import org.eclipse.xsd.util.XSDConstants; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.ProcessingInstruction; |
| |
| // public class XSDEditor extends StructuredTextMultiPageEditorPart |
| public class XSDEditor extends XSDMultiPageEditorPart implements ITabbedPropertySheetPageContributor |
| { |
| protected XSDTextEditor textEditor; |
| IFile resourceFile; |
| XSDSelectionManager xsdSelectionManager; |
| |
| private IStructuredModel result; |
| private XMLModelImpl model; |
| |
| public XSDEditor() |
| { |
| super(); |
| xsdSelectionManager = new XSDSelectionManager(); |
| } |
| |
| InternalPartListener partListener = new InternalPartListener(this); |
| |
| // show outline view - defect 266116 |
| public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException |
| { |
| super.init(site, editorInput); |
| |
| IWorkbenchWindow dw=PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| IWorkbenchPage page=dw.getActivePage(); |
| getSite().getPage().addPartListener(partListener); |
| try |
| { |
| if (page != null) |
| { |
| // page.showView("org.eclipse.ui.views.ContentOutline"); |
| page.showView("org.eclipse.ui.views.PropertySheet"); |
| } |
| } catch (PartInitException e) |
| { |
| // e.printStackTrace(); |
| } |
| } |
| |
| // For team support |
| // protected PropertyDirtyChangeListener propertyChangeListener; |
| |
| /** |
| * Creates the pages of this multi-page editor. |
| * <p> |
| * Subclasses of <code>MultiPageEditor</code> must implement this method. |
| * </p> |
| */ |
| protected void createPages() |
| { |
| try |
| { |
| if (!loadFile()) |
| return; |
| |
| // source page MUST be created before design page, now |
| createSourcePage(); |
| |
| addSourcePage(); |
| buildXSDModel(); |
| |
| // comment this line out to hide the graph page |
| // |
| createAndAddGraphPage(); |
| |
| int pageIndexToShow = getDefaultPageTypeIndex(); |
| setActivePage(pageIndexToShow); |
| |
| addCommandStackListener(); |
| |
| XSDEditorPlugin.getPlugin().getPreferenceStore().addPropertyChangeListener(preferenceStoreListener); |
| } |
| catch (PartInitException exception) |
| { |
| throw new SourceEditingRuntimeException(SSECorePlugin.getResourceString("An_error_has_occurred_when1_ERROR_")); //$NON-NLS-1$ = "An error has occurred when initializing the input for the the editor's source page." |
| } |
| } |
| |
| public String[] getPropertyCategories() |
| { |
| return new String[] { "general", "namespace", "other", "attributes", "documentation", "facets" }; //$NON-NLS-1$ |
| } |
| |
| /** |
| * @see org.eclipse.wst.common.ui.properties.ITabbedPropertySheetPageContributor#getContributorId() |
| */ |
| public String getContributorId() |
| { |
| return "org.eclipse.wst.xsd.ui.internal.XSDEditor"; |
| //return getSite().getId(); |
| } |
| |
| protected CommandStackListener commandStackListener; |
| protected void addCommandStackListener() |
| { |
| if (commandStackListener == null) |
| { |
| IStructuredTextUndoManager undoManager = getModel().getUndoManager(); |
| commandStackListener = new CommandStackListener() |
| { |
| /** |
| * @see org.eclipse.emf.common.command.CommandStackListener#commandStackChanged(EventObject) |
| */ |
| public void commandStackChanged(EventObject event) |
| { |
| Object obj = event.getSource(); |
| if (obj instanceof BasicCommandStack) |
| { |
| BasicCommandStack stack = (BasicCommandStack) obj; |
| Command recentCommand = stack.getMostRecentCommand(); |
| Command redoCommand = stack.getRedoCommand(); |
| Command undoCommand = stack.getUndoCommand(); |
| if (recentCommand == redoCommand) |
| { |
| // there must have been an undo reset info tasks |
| resetInformationTasks(); |
| } |
| } |
| } |
| }; |
| |
| //TODO WTP Port undoManager.getCommandStack().addCommandStackListener(commandStackListener); |
| |
| } |
| } |
| |
| protected void pageChange(int arg) |
| { |
| super.pageChange(arg); |
| } |
| |
| protected void removeCommandStackListener() |
| { |
| if (commandStackListener != null) |
| { |
| IStructuredTextUndoManager undoManager = getModel().getUndoManager(); |
| //TODO WTP Port undoManager.getCommandStack().removeCommandStackListener(commandStackListener); |
| } |
| } |
| |
| // This is from the IValidateEditEditor interface |
| /* public void undoChange() |
| { |
| StructuredTextUndoManager undoManager = textEditor.getModel().getUndoManager(); |
| undoManager.undo(); |
| // Make the editor clean |
| textEditor.getModel().setDirtyState(false); |
| } */ |
| |
| private class PreferenceStoreListener implements IPropertyChangeListener |
| { |
| /** |
| * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent) |
| */ |
| public void propertyChange(PropertyChangeEvent event) |
| { |
| } |
| } |
| |
| protected IPropertyChangeListener preferenceStoreListener = new PreferenceStoreListener(); |
| |
| protected int getDefaultPageTypeIndex() |
| { |
| int pageIndex = sourcePageIndex; |
| |
| if (XSDEditorPlugin.getPlugin().getDefaultPage().equals(XSDEditorPlugin.GRAPH_PAGE)) |
| { |
| if (graphPageIndex != -1) |
| pageIndex = graphPageIndex; |
| } |
| |
| return pageIndex; |
| } |
| |
| int currentPage = -1; |
| public String getCurrentPageType() |
| { |
| // should update pref. for valid pages |
| if (getActivePage() != -1) |
| { |
| currentPage = getActivePage(); |
| } |
| if (currentPage == graphPageIndex) |
| { |
| return XSDEditorPlugin.GRAPH_PAGE; |
| } |
| else |
| { |
| return XSDEditorPlugin.SOURCE_PAGE; |
| } |
| } |
| |
| public Object getActivePart() |
| { |
| return getSite().getWorkbenchWindow().getActivePage().getActivePart(); |
| } |
| |
| public void dispose() |
| { |
| // propertyChangeListener.dispose(); |
| removeCommandStackListener(); |
| |
| XSDEditorPlugin.getPlugin().setDefaultPage(getCurrentPageType()); |
| XSDEditorPlugin.getPlugin().getPreferenceStore().removePropertyChangeListener(preferenceStoreListener); |
| |
| getSite().getPage().removePartListener(partListener); |
| |
| super.dispose(); |
| } |
| |
| protected boolean loadFile() |
| { |
| Object input = getEditorInput(); |
| |
| if (input instanceof IFileEditorInput) |
| { |
| resourceFile = ((IFileEditorInput) input).getFile(); |
| } |
| else if (input instanceof JavaFileEditorInput) |
| { |
| IPath path = ((JavaFileEditorInput)input).getPath(input); |
| String ext = path.getFileExtension(); |
| if (ext != null && ext.equals("xsd")) |
| { |
| return true; |
| } |
| return false; |
| } |
| else |
| { |
| // XSDEditorPlugin.getPlugin().getMsgLogger().write("###Error...XSDEditor::createPages() .. Can't find input..Exiting.."); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Method openOnGlobalReference. |
| * The comp argument is a resolved xsd schema object from another file. This is created and called from another |
| * schema model to allow F3 navigation to open a new editor and choose the referenced object within that editor context |
| * @param comp |
| */ |
| public void openOnGlobalReference(XSDConcreteComponent comp) |
| { |
| openOnSelectionHelper.openOnGlobalReference(comp); |
| } |
| |
| protected OpenOnSelectionHelper openOnSelectionHelper; |
| |
| public OpenOnSelectionHelper getOpenOnSelectionHelper() |
| { |
| return openOnSelectionHelper; |
| } |
| |
| /** |
| * @see org.eclipse.wst.xsd.ui.internal.XSDMultiPageEditorPart#createTextEditor() |
| */ |
| protected StructuredTextEditor createTextEditor() |
| { |
| return new XSDTextEditor(this); |
| } |
| |
| /* |
| * @see StructuredTextMultiPageEditorPart#createSourcePage() |
| */ |
| protected void createSourcePage() throws PartInitException |
| { |
| super.createSourcePage(); |
| |
| textEditor = (XSDTextEditor) getTextEditor(); |
| |
| openOnSelectionHelper = new OpenOnSelectionHelper(textEditor); |
| } |
| |
| int sourcePageIndex = -1; |
| /** |
| * Adds the source page of the multi-page editor. |
| */ |
| protected void addSourcePage() throws PartInitException { |
| |
| sourcePageIndex = addPage(textEditor, getEditorInput()); |
| setPageText(sourcePageIndex, XSDEditorPlugin.getXSDString("_UI_TAB_SOURCE")); |
| |
| // defect 223043 ... do textEditor.setModel() here instead of in createSourcePage() |
| // the update's critical, to get viewer selection manager and highlighting to work |
| IEditorInput editorInput = getEditorInput(); |
| if (editorInput instanceof IFileEditorInput) |
| { |
| textEditor.setModel((IFileEditorInput)getEditorInput()); |
| } |
| else |
| { |
| // textEditor.setModel(editorInput); |
| } |
| textEditor.update(); |
| firePropertyChange(PROP_TITLE); |
| } |
| |
| int graphPageIndex = -1; |
| XSDGraphViewer graphViewer; |
| |
| /** |
| * Creates the graph page and adds it to the multi-page editor. |
| */ |
| protected void createAndAddGraphPage() throws PartInitException |
| { |
| graphViewer = new XSDGraphViewer(this); |
| graphViewer.setSchema(xsdSchema); |
| Control graphControl = graphViewer.createControl(getContainer()); |
| graphPageIndex = addPage(graphControl); |
| setPageText(graphPageIndex, XSDEditorPlugin.getXSDString("_UI_TAB_GRAPH")); |
| |
| // graphViewer.setViewerSelectionManager(textEditor.getViewerSelectionManager()); |
| graphViewer.setSelectionManager(getSelectionManager()); |
| |
| // this forces the editor to initially select the top level schema object |
| // |
| getSelectionManager().setSelection(new StructuredSelection(textEditor.getXSDSchema())); |
| } |
| |
| /* |
| * @see IAdaptable#getAdapter(Class) |
| */ |
| public Object getAdapter(Class key) |
| { |
| Object result = null; |
| if (key == ISelectionProvider.class) |
| { |
| result = xsdSelectionManager; |
| } |
| else |
| { |
| result = textEditor.getAdapter(key); |
| } |
| return result; |
| } |
| |
| public XSDSelectionManager getSelectionManager() |
| { |
| return xsdSelectionManager; |
| } |
| |
| /** |
| * @see org.eclipse.wst.xsd.ui.internal.XSDMultiPageEditorPart#doSaveAs() |
| */ |
| public void doSaveAs() |
| { |
| super.doSaveAs(); |
| } |
| |
| public void doSave(org.eclipse.core.runtime.IProgressMonitor monitor) |
| { |
| super.doSave(monitor); |
| } |
| |
| protected XSDSchema xsdSchema; |
| protected ResourceSet resourceSet; |
| |
| public void reparseSchema() |
| { |
| Document document = ((XMLModel)getModel()).getDocument(); |
| createSchema(document.getDocumentElement()); |
| } |
| |
| public XSDSchema createSchema(Node node) |
| { |
| try |
| { |
| EPackage.Registry reg = EPackage.Registry.INSTANCE; |
| XSDPackage xsdPackage = (XSDPackage)reg.getEPackage(XSDPackage.eNS_URI); |
| xsdSchema = xsdPackage.getXSDFactory().createXSDSchema(); |
| |
| // Force the loading of the "meta" schema for schema instance instance. |
| // |
| String schemaForSchemaNamespace = node.getNamespaceURI(); |
| XSDSchemaImpl.getSchemaForSchema(schemaForSchemaNamespace); |
| |
| resourceSet = XSDSchemaImpl.createResourceSet(); |
| resourceSet.setURIConverter(new XSDURIConverter(resourceFile)); |
| |
| String pathName = ""; |
| // If the resource is in the workspace.... |
| // otherwise the user is trying to open an external file |
| if (resourceFile != null) |
| { |
| pathName = resourceFile.getFullPath().toString(); |
| Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(pathName), true); |
| // resource.getContents().add(xsdSchema); |
| resourceSet.getResources().add(resource); |
| |
| Object obj = resource.getContents().get(0); |
| if (obj instanceof XSDSchema) |
| { |
| xsdSchema = (XSDSchema)obj; |
| } |
| |
| // URIConverter uriConverter = resourceSet.getURIConverter(); |
| // resourceSet.setURIConverter(new XSDURIConverter(resourceFile)); |
| |
| xsdSchema.setElement((Element)node); |
| resource.setModified(false); |
| } |
| else |
| { |
| xsdSchema.setElement((Element)node); |
| } |
| } |
| catch (StackOverflowError e) |
| { |
| // XSDEditorPlugin.getPlugin().getMsgLogger().write("Stack overflow encountered. Possibly an invalid recursive circular schema"); |
| } |
| catch (Exception ex) |
| { |
| // ex.printStackTrace(); |
| } |
| |
| return xsdSchema; |
| } |
| |
| class XSDDocumentAdapter extends DocumentAdapter |
| { |
| INodeNotifier currentNotifier; |
| int currentEventType; |
| |
| public XSDDocumentAdapter(Document document) |
| { |
| super(document); |
| } |
| |
| boolean handlingNotifyChanged = false; |
| |
| public void notifyChanged(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index) |
| { |
| if (!handlingNotifyChanged) |
| { |
| handlingNotifyChanged = true; |
| try |
| { |
| // delay handle events only in the source view |
| if (getCurrentPageType() == XSDEditorPlugin.SOURCE_PAGE && |
| !(getActivePart() instanceof PropertySheet) && |
| !(getActivePart() instanceof org.eclipse.ui.views.contentoutline.ContentOutline)) { |
| startDelayedEvent(notifier, eventType, feature, oldValue, newValue, index); |
| } |
| else // all other views, just handle the events right away |
| { |
| handleNotifyChange(notifier, eventType, feature, oldValue, newValue, index); |
| } |
| } |
| catch (Exception e) |
| { |
| // XSDEditorPlugin.getPlugin().getMsgLogger().write(e); |
| } |
| handlingNotifyChanged = false; |
| } |
| } |
| |
| public void handleNotifyChange(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index) |
| { |
| // System.out.println(eventType + " : HandleNotifyChange " + notifier.hashCode() + " notifier " + notifier); |
| switch (eventType) |
| { |
| case INodeNotifier.ADD: |
| { |
| if (newValue instanceof Element) |
| { |
| adapt((Element)newValue); |
| // Add updateParentForDerivation(node, listener); |
| } |
| break; |
| } |
| case INodeNotifier.REMOVE: |
| { |
| Node node = (Node)notifier; |
| XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node); |
| |
| if (listener instanceof XSDSchema) |
| { |
| // we want to reset the schema's external elements when the directive is deleted |
| if (feature instanceof Element) |
| { |
| Element elem = (Element)feature; |
| if (XSDDOMHelper.inputEquals(elem, XSDConstants.INCLUDE_ELEMENT_TAG, false) || |
| XSDDOMHelper.inputEquals(elem, XSDConstants.IMPORT_ELEMENT_TAG, false) || |
| XSDDOMHelper.inputEquals(elem, XSDConstants.REDEFINE_ELEMENT_TAG, false)) |
| { |
| xsdSchema.reset(); |
| xsdSchema.update(); |
| } |
| } |
| } |
| } |
| case INodeNotifier.CHANGE: |
| { |
| Node node = (Node)notifier; |
| XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node); |
| if (node.getNodeType() == Node.ELEMENT_NODE) |
| { |
| listener.elementAttributesChanged((Element)node); |
| listener.elementChanged((Element)node); |
| } |
| else if (node.getNodeType() == Node.DOCUMENT_NODE) |
| { |
| listener.elementAttributesChanged(((Document)node).getDocumentElement()); |
| listener.elementChanged(((Document)node).getDocumentElement()); |
| } |
| break; |
| } |
| case INodeNotifier.STRUCTURE_CHANGED: |
| case INodeNotifier.CONTENT_CHANGED: |
| { |
| Node node = (Node)notifier; |
| XSDConcreteComponent listener = xsdSchema.getCorrespondingComponent(node); |
| if (node.getNodeType() == Node.ELEMENT_NODE) |
| { |
| listener.elementContentsChanged((Element)node); |
| break; |
| } |
| else if (node.getNodeType() == Node.DOCUMENT_NODE) |
| { |
| Element docElement = ((Document)node).getDocumentElement(); |
| // Need to add check if doc element is being edited in the source |
| if (docElement != null) |
| { |
| String prefix = docElement.getPrefix(); |
| String xmlnsString = prefix == null? "xmlns" : "xmlns:" + prefix; |
| Attr attr = docElement.getAttributeNode(xmlnsString); |
| boolean doParse = false; |
| if (attr != null) |
| { |
| if (attr.getValue().equals(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001) && docElement.getLocalName().equals("schema")) |
| { |
| // We have a viable schema so parse it |
| doParse = true; |
| } |
| } |
| |
| if (doParse) |
| { |
| adapt(docElement); |
| xsdSchema.setElement(docElement); |
| } |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| protected DelayedEvent delayedTask; |
| protected void startDelayedEvent(INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index) |
| { |
| // System.out.println("start delayed event"); |
| // check if there is already a delayed task for the same notifier and eventType |
| // if (delayedTask != null) |
| // { |
| // Notifier aNotifier = delayedTask.getNotifier(); |
| // int anEventType = delayedTask.getEventType(); |
| // if (notifier == aNotifier && anEventType == eventType) |
| // { |
| // // same event, just different data, delay new event |
| // delayedTask.setCancel(true); |
| // } |
| // } |
| |
| delayedTask = new DelayedEvent(); |
| |
| delayedTask.setNotifier(notifier); |
| delayedTask.setEventType(eventType); |
| delayedTask.setFeature(feature); |
| delayedTask.setOldValue(oldValue); |
| delayedTask.setNewValue(newValue); |
| delayedTask.setIndex(index); |
| |
| Display.getDefault().timerExec(400,delayedTask); |
| } |
| |
| class DelayedEvent implements Runnable |
| { |
| INodeNotifier notifier; |
| int eventType; |
| Object feature; |
| Object oldValue; |
| Object newValue; |
| int index; |
| boolean cancelEvent = false; |
| |
| /* |
| * @see Runnable#run() |
| */ |
| public void run() |
| { |
| if (!cancelEvent) |
| { |
| handleNotifyChange(notifier, eventType, feature, oldValue, newValue, index); |
| if (delayedTask == this) |
| { |
| delayedTask = null; |
| } |
| } |
| } |
| |
| public void setCancel(boolean flag) |
| { |
| cancelEvent = flag; |
| } |
| |
| public void setNotifier(INodeNotifier notifier) |
| { |
| this.notifier = notifier; |
| } |
| |
| public void setEventType(int eventType) |
| { |
| this.eventType = eventType; |
| } |
| |
| public void setFeature(Object feature) |
| { |
| this.feature = feature; |
| } |
| |
| public void setOldValue(Object oldValue) |
| { |
| this.oldValue = oldValue; |
| } |
| |
| public void setNewValue(Object newValue) |
| { |
| this.newValue = newValue; |
| } |
| |
| public void setIndex(int index) |
| { |
| this.index = index; |
| } |
| |
| public INodeNotifier getNotifier() |
| { |
| return notifier; |
| } |
| |
| public int getEventType() |
| { |
| return eventType; |
| } |
| |
| public Object getNewValue() |
| { |
| return newValue; |
| } |
| |
| public Object getOldValue() |
| { |
| return oldValue; |
| } |
| |
| } |
| } |
| |
| abstract class DocumentAdapter implements INodeAdapter |
| { |
| public DocumentAdapter(Document document) |
| { |
| ((INodeNotifier)document).addAdapter(this); |
| adapt(document.getDocumentElement()); |
| } |
| |
| public void adapt(Element element) |
| { |
| if (((INodeNotifier)element).getExistingAdapter(this) == null) |
| { |
| |
| ((INodeNotifier)element).addAdapter(this); |
| |
| for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) |
| { |
| if (child.getNodeType() == Node.ELEMENT_NODE) |
| { |
| adapt((Element)child); |
| } |
| } |
| } |
| } |
| |
| public boolean isAdapterForType(Object type) |
| { |
| return type == this; |
| } |
| |
| abstract public void notifyChanged |
| (INodeNotifier notifier, int eventType, Object feature, Object oldValue, Object newValue, int index); |
| } |
| |
| |
| /** |
| * Method createDefaultSchemaNode. Should only be called to insert a schema node into an empty document |
| */ |
| public void createDefaultSchemaNode() |
| { |
| Document document = ((XMLModel)getModel()).getDocument(); |
| if (document.getChildNodes().getLength() == 0) |
| { |
| // if it is a completely empty file, then add the encoding and version processing instruction |
| //TODO String encoding = EncodingHelper.getDefaultEncodingTag(); |
| String encoding = "UTF-8"; |
| ProcessingInstruction instr = document.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"" + encoding + "\""); |
| document.appendChild(instr); |
| } |
| |
| // Create a default schema tag now |
| |
| // String defaultPrefixForTargetNamespace = getFileResource().getProjectRelativePath().removeFileExtension().lastSegment(); |
| String defaultPrefixForTargetNamespace = "tns"; |
| String prefixForSchemaNamespace = ""; |
| String schemaNamespaceAttribute = "xmlns"; |
| if (XSDEditorPlugin.getPlugin().isQualifyXMLSchemaLanguage()) |
| { |
| // Added this if check before disallowing blank prefixes in the preferences... |
| // Can take this out. See also NewXSDWizard |
| if (XSDEditorPlugin.getPlugin().getXMLSchemaPrefix().trim().length() > 0) |
| { |
| prefixForSchemaNamespace = XSDEditorPlugin.getPlugin().getXMLSchemaPrefix() + ":"; |
| schemaNamespaceAttribute += ":" + XSDEditorPlugin.getPlugin().getXMLSchemaPrefix(); |
| } |
| } |
| |
| document.appendChild(document.createTextNode("\n")); |
| Element element = document.createElement(prefixForSchemaNamespace + XSDConstants.SCHEMA_ELEMENT_TAG); |
| |
| element.setAttribute(schemaNamespaceAttribute,"http://www.w3.org/2001/XMLSchema"); |
| |
| String defaultTargetURI = XSDEditorPlugin.getPlugin().getXMLSchemaTargetNamespace(); |
| element.setAttribute(XSDConstants.TARGETNAMESPACE_ATTRIBUTE, defaultTargetURI); |
| element.setAttribute("xmlns:" + defaultPrefixForTargetNamespace, defaultTargetURI); |
| |
| document.appendChild(element); |
| } |
| |
| public void buildXSDModel() |
| { |
| try |
| { |
| Document document = ((XMLModel)getModel()).getDocument(); |
| if (document.getChildNodes().getLength() == 0) |
| { |
| // this is an empty document. Create a default schema tag now |
| createDefaultSchemaNode(); |
| } |
| |
| createSchema(document.getDocumentElement()); |
| |
| XSDDocumentAdapter documentAdapter = |
| new XSDDocumentAdapter(((XMLModel)getModel()).getDocument()); |
| } |
| catch (Exception e) |
| { |
| // XSDEditorPlugin.getPlugin().getMsgLogger().write("Failed to create Model"); |
| // XSDEditorPlugin.getPlugin().getMsgLogger().write(e); |
| // e.printStackTrace(); |
| } |
| |
| |
| |
| // XSDResourceFactoryImpl.validate(xsdSchema, input.getFile().getContents(true)); |
| } |
| |
| // private void updateParentForDerivation(Node node, XSDConcreteComponent correspondingComponent) |
| // { |
| // if (XSDDOMHelper.inputEquals(node, XSDConstants.SIMPLECONTENT_ELEMENT_TAG, false)|| |
| // XSDDOMHelper.inputEquals(node,XSDConstants.COMPLEXCONTENT_ELEMENT_TAG,false)) |
| // { |
| // XSDComplexTypeDefinition xsdComplexTypeDefinition = |
| // correspondingComponent.getContainer() instanceof XSDComplexTypeDefinition ? |
| // (XSDComplexTypeDefinition)correspondingComponent.getContainer() : |
| // null; |
| // if (xsdComplexTypeDefinition != null) |
| // { |
| // xsdComplexTypeDefinition.elementContentsChanged(xsdComplexTypeDefinition.getElement()); |
| // } |
| // } |
| // } |
| |
| // private void checkUnion(Node node, XSDConcreteComponent correspondingComponent, int i) |
| // { |
| // // bug 219967 - union changes to restriction |
| // if (XSDDOMHelper.inputEquals(node, XSDConstants.UNION_ELEMENT_TAG, false)) |
| // { |
| //// XSDConcreteComponent comp = correspondingComponent.getContainer(); |
| //// if (comp != null) |
| //// { |
| //// switch (i) |
| //// { |
| //// case 1: |
| //// comp.elementAttributesChanged((Element)node); |
| //// break; |
| //// case 4: |
| //// comp.elementContentsChanged((Element)node); |
| //// break; |
| //// } |
| //// } |
| // } |
| // else |
| // { |
| // switch (i) |
| // { |
| // case 1: |
| // case 4: |
| // // do both types of updates since sometimes the attributes have changed indirectly |
| // // because the content has changed |
| // correspondingComponent.elementAttributesChanged((Element)node); |
| // correspondingComponent.elementContentsChanged((Element)node); |
| // break; |
| // } |
| // } |
| // } |
| |
| // private void updateMap(XSDConcreteComponent listener, Element documentElement) |
| // { |
| // boolean handleChangeInSchema = false; |
| // if (listener instanceof XSDSchema) |
| // { |
| // if (!handleChangeInSchema) |
| // { |
| // handleChangeInSchema = true; |
| // XSDSchema xsdSchema = (XSDSchema)listener; |
| // java.util.Map prefixToNameSpaceMap = xsdSchema.getQNamePrefixToNamespaceMap(); |
| // String targetNamespace = xsdSchema.getTargetNamespace(); |
| //// System.out.println("targetNamespace = " + targetNamespace); |
| // |
| // NamedNodeMap attributes = documentElement.getAttributes(); |
| // int length = attributes.getLength(); |
| // |
| // ArrayList keyList = new ArrayList(); |
| // keyList.addAll(prefixToNameSpaceMap.keySet()); |
| // |
| // String key; |
| // |
| // |
| // // update the map when the prefix is changed |
| // CHECK: for (int i = 0; i < length; i++) |
| // { |
| // Attr attr = (Attr)attributes.item(i); |
| // String name = attr.getNodeName(); |
| // |
| // if (isValidXMLNSAttribute(name)) |
| //// if (name.startsWith("xmlns")) |
| // { |
| // String value = attr.getNodeValue(); |
| // if (value == null) |
| // { |
| // break CHECK; |
| // } |
| // int index = name.indexOf(":"); |
| // key = index == -1 ? null : name.substring(index + 1); |
| //// System.out.println(" Attribute key is " + key + " , value = " + value); |
| //// System.out.println(" map.get(key) = " + prefixToNameSpaceMap.get(key)); |
| // if (!prefixToNameSpaceMap.containsKey(key)) |
| // { |
| // for (Iterator iter = keyList.iterator(); iter.hasNext(); ) |
| // { |
| // String aPrefix = (String)iter.next(); |
| //// System.out.println(" --> A Map Prefix is " + aPrefix); |
| //// System.out.println(" --> model map.get(prefix) " + prefixToNameSpaceMap.get(aPrefix)); |
| // if (prefixToNameSpaceMap.get(aPrefix) != null) |
| // { |
| // if (prefixToNameSpaceMap.get(aPrefix).equals(value)) |
| // { |
| // prefixToNameSpaceMap.remove(aPrefix); |
| // } |
| // } |
| // } |
| // } |
| // else if (prefixToNameSpaceMap.containsKey(key)) |
| // { |
| // if (prefixToNameSpaceMap.get(key) != null) |
| // { |
| // if (!prefixToNameSpaceMap.get(key).equals(value)) |
| // { |
| // Set entrySet = prefixToNameSpaceMap.entrySet(); |
| // for (Iterator iter = entrySet.iterator(); iter.hasNext(); ) |
| // { |
| // Map.Entry aMapEntry = (Map.Entry)iter.next(); |
| // if ( (key != null && (aMapEntry.getKey() != null && aMapEntry.getKey().equals(key))) |
| // || (key == null && (aMapEntry.getKey() == null))) |
| // { |
| // aMapEntry.setValue(value); |
| // } |
| // } |
| // } |
| // } |
| // else |
| // { |
| // Set entrySet = prefixToNameSpaceMap.entrySet(); |
| // for (Iterator iter = entrySet.iterator(); iter.hasNext(); ) |
| // { |
| // Map.Entry aMapEntry = (Map.Entry)iter.next(); |
| // if ( (key != null && (aMapEntry.getKey() != null && aMapEntry.getKey().equals(key))) |
| // || (key == null && (aMapEntry.getKey() == null))) |
| // { |
| // aMapEntry.setValue(value); |
| // } |
| // } |
| // } |
| // } |
| // } |
| // } |
| // |
| // boolean modelMapPrefixFound = false; |
| // for (Iterator iter = keyList.iterator(); iter.hasNext(); ) |
| // { |
| // String aPrefix = (String)iter.next(); |
| // modelMapPrefixFound = false; |
| // attributes = documentElement.getAttributes(); |
| // length = attributes.getLength(); |
| // |
| // for (int i = 0; i < length; i++) |
| // { |
| // Attr attr = (Attr)attributes.item(i); |
| // if (attr != null) |
| // { |
| // String name = attr.getNodeName(); |
| // |
| // // if (name.startsWith("xmlns")) |
| // if (isValidXMLNSAttribute(name)) |
| // { |
| // String value = attr.getNodeValue(); |
| // int index = name.indexOf(":"); |
| // key = index == -1 ? null : name.substring(index + 1); |
| // if (aPrefix == null && key == null) |
| // { |
| // modelMapPrefixFound = true; |
| // } |
| // else if (aPrefix != null && (aPrefix.equals(key))) |
| // { |
| // modelMapPrefixFound = true; |
| // if ((prefixToNameSpaceMap.get(key) != null && !prefixToNameSpaceMap.get(key).equals(value)) |
| // || (prefixToNameSpaceMap.get(key) == null && value != null)) |
| // { |
| // if (value != null && value.length() > 0) |
| // { |
| // prefixToNameSpaceMap.put(aPrefix, value); |
| // } |
| // } |
| // } |
| // else if (key != null && (key.equals(aPrefix))) |
| // { |
| // modelMapPrefixFound = true; |
| // } |
| // } |
| // } |
| // } |
| // if (!modelMapPrefixFound) |
| // { |
| // prefixToNameSpaceMap.remove(aPrefix); |
| // } |
| // } |
| // |
| // // to ensure map is recreated |
| //// XSDSchemaHelper.updateElement(xsdSchema); |
| //// reparseSchema(); |
| // |
| // handleChangeInSchema = false; |
| // |
| //// System.out.println("XSDeditor Map is " + prefixToNameSpaceMap.values()); |
| //// System.out.println("XSDeditor Map keys are " + prefixToNameSpaceMap.keySet()); |
| // |
| // } |
| // } |
| // } |
| |
| /** |
| * Returns the xsdSchema. |
| * @return XSDSchema |
| */ |
| public XSDSchema getXSDSchema() |
| { |
| return xsdSchema; |
| } |
| |
| |
| /** |
| * Returns the resourceFile. |
| * @return IFile |
| */ |
| public IFile getFileResource() |
| { |
| return resourceFile; |
| } |
| |
| /** |
| * Get the IDocument from the text viewer |
| */ |
| public IDocument getEditorIDocument() |
| { |
| IDocument document = textEditor.getTextViewer().getDocument(); |
| return document; |
| } |
| |
| /** |
| * Create ref integrity tasks in task list |
| */ |
| public void createTasksInTaskList(ArrayList messages) |
| { |
| // DisplayErrorInTaskList tasks = new DisplayErrorInTaskList(getEditorIDocument(), getFileResource(), messages); |
| // tasks.run(); |
| } |
| |
| public void resetInformationTasks() |
| { |
| // DisplayErrorInTaskList.removeInfoMarkers(getFileResource()); |
| } |
| |
| public XSDGraphViewer getGraphViewer() |
| { |
| return graphViewer; |
| } |
| |
| // /** |
| // * @see org.eclipse.ui.part.MultiPageEditorPart#handlePropertyChange(int) |
| // */ |
| // protected void handlePropertyChange(int propertyId) |
| // { |
| // super.handlePropertyChange(propertyId); |
| // |
| // if (propertyId == IEditorPart.PROP_INPUT) |
| // { |
| // setInput(textEditor.getEditorInput()); |
| // resourceFile = ((IFileEditorInput) getEditorInput()).getFile(); |
| // setTitle(resourceFile.getName()); |
| //// outline.setModel(getModel()); |
| // |
| // // even though we've set title etc., several times already! |
| // // only now is all prepared for it. |
| // firePropertyChange(IWorkbenchPart.PROP_TITLE); |
| // firePropertyChange(PROP_DIRTY); |
| // } |
| // else if (propertyId == IEditorPart.PROP_TITLE) |
| // { |
| // if (getEditorInput() != textEditor.getEditorInput()) |
| // { |
| // setInput(textEditor.getEditorInput()); |
| // } |
| // } |
| // } |
| |
| public IEditorPart getActiveEditorPage() |
| { |
| return getActiveEditor(); |
| } |
| |
| public XSDTextEditor getXSDTextEditor() |
| { |
| return textEditor; |
| } |
| |
| class InternalPartListener implements IPartListener |
| { |
| XSDEditor editor; |
| public InternalPartListener(XSDEditor editor) |
| { |
| this.editor = editor; |
| } |
| |
| public void partActivated(IWorkbenchPart part) |
| { |
| if (part == editor) |
| { |
| ISelection selection = getSelectionManager().getSelection(); |
| if (selection != null) |
| { |
| if (getCurrentPageType().equals(XSDEditorPlugin.GRAPH_PAGE)) |
| { |
| getSelectionManager().selectionChanged(new SelectionChangedEvent(editor.getGraphViewer().getComponentViewer(), selection)); |
| } |
| else if (getCurrentPageType().equals(XSDEditorPlugin.SOURCE_PAGE)) |
| { |
| getSelectionManager().setSelection(selection); |
| } |
| } |
| } |
| } |
| |
| public void partBroughtToTop(IWorkbenchPart part) |
| { |
| } |
| |
| public void partClosed(IWorkbenchPart part) |
| { |
| } |
| |
| |
| public void partDeactivated(IWorkbenchPart part) |
| { |
| } |
| |
| public void partOpened(IWorkbenchPart part) |
| { |
| } |
| } |
| |
| } |