kchong | 9fe072d | 2007-05-02 18:10:23 +0000 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2001, 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 | *******************************************************************************/ |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 11 | package org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo; |
| 12 | |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 13 | import java.text.Collator; |
| 14 | import java.util.Arrays; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 15 | import java.util.Collection; |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 16 | import java.util.Comparator; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 17 | import java.util.HashMap; |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 18 | import java.util.Iterator; |
csalter | bb1e4ef | 2006-05-17 03:39:24 +0000 | [diff] [blame] | 19 | import java.util.List; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 20 | import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration; |
| 21 | import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 22 | import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; |
| 23 | import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 24 | import org.eclipse.wst.xml.ui.internal.tabletree.TreeContentHelper; |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 25 | import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.custom.DefaultListNodeEditorConfiguration; |
| 26 | import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.custom.NodeCustomizationRegistry; |
| 27 | import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.custom.NodeEditorConfiguration; |
| 28 | import org.eclipse.wst.xsd.ui.internal.common.properties.sections.appinfo.custom.NodeEditorProvider; |
| 29 | import org.eclipse.wst.xsd.ui.internal.editor.XSDEditorPlugin; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 30 | import org.w3c.dom.Attr; |
| 31 | import org.w3c.dom.Element; |
| 32 | import org.w3c.dom.NamedNodeMap; |
| 33 | |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 34 | public class DOMExtensionDetailsContentProvider implements ExtensionDetailsContentProvider |
| 35 | { |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 36 | private static final Object[] EMPTY_ARRAY = {}; |
| 37 | private static final String[] EMPTY_STRING_ARRAY = {}; |
| 38 | private static final String XMLNS = "xmlns"; //$NON-NLS |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 39 | private static final String TEXT_NODE_KEY = "text()"; //$NON-NLS |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 40 | |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 41 | public Object[] getItems(Object input) |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 42 | { |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 43 | HashMap resultMap = new HashMap(); |
| 44 | if (input instanceof Element) |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 45 | { |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 46 | Element element = (Element) input; |
| 47 | |
| 48 | // here we compute items for the attributes that physically in the document |
| 49 | // |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 50 | NamedNodeMap attributes = element.getAttributes(); |
| 51 | for (int i = 0; i < attributes.getLength(); i++) |
| 52 | { |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 53 | Attr attr = (Attr) attributes.item(i); |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 54 | if (!XMLNS.equals(attr.getName()) && !XMLNS.equals(attr.getPrefix())) //$NON-NLS-1$ //$NON-NLS-2$ |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 55 | { |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 56 | resultMap.put(attr.getName(), DOMExtensionItem.createItemForElementAttribute(element, attr)); |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 57 | } |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 58 | } |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 59 | |
| 60 | // here we compute an item for the text node that is physically in the document |
| 61 | // |
| 62 | String textNodeValue = new TreeContentHelper().getNodeValue(element); |
| 63 | if (textNodeValue != null) |
| 64 | { |
| 65 | resultMap.put(TEXT_NODE_KEY, DOMExtensionItem.createItemForElementText(element)); |
| 66 | } |
| 67 | |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 68 | ModelQuery modelQuery = ModelQueryUtil.getModelQuery(element.getOwnerDocument()); |
| 69 | if (modelQuery != null) |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 70 | { |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 71 | CMElementDeclaration ed = modelQuery.getCMElementDeclaration(element); |
| 72 | if (ed != null) |
| 73 | { |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 74 | // here we compute items for the attributes that may be added to the document according to the grammar |
| 75 | // |
csalter | bb1e4ef | 2006-05-17 03:39:24 +0000 | [diff] [blame] | 76 | List list = modelQuery.getAvailableContent(element, ed, ModelQuery.INCLUDE_ATTRIBUTES); |
| 77 | for (Iterator i = list.iterator(); i.hasNext(); ) |
| 78 | { |
| 79 | CMAttributeDeclaration ad = (CMAttributeDeclaration)i.next(); |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 80 | if (ad != null && resultMap.get(ad.getNodeName()) == null) |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 81 | { |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 82 | resultMap.put(ad.getNodeName(), DOMExtensionItem.createItemForElementAttribute(element, ad)); |
csalter | bb1e4ef | 2006-05-17 03:39:24 +0000 | [diff] [blame] | 83 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 84 | } |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 85 | if (resultMap.get(TEXT_NODE_KEY) == null) |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 86 | { |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 87 | // here we compute an item for the text node that may be added to the document according to the grammar |
| 88 | // |
| 89 | int contentType = ed.getContentType(); |
| 90 | if (contentType == CMElementDeclaration.PCDATA || contentType == CMElementDeclaration.MIXED) |
| 91 | { |
| 92 | resultMap.put(TEXT_NODE_KEY, DOMExtensionItem.createItemForElementText(element)); |
| 93 | } |
| 94 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 95 | } |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 96 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 97 | Collection collection = resultMap.values(); |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 98 | // initialize the editor information for each item |
| 99 | // |
| 100 | for (Iterator i = collection.iterator(); i.hasNext();) |
| 101 | { |
| 102 | initPropertyEditorConfiguration((DOMExtensionItem) i.next()); |
| 103 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 104 | DOMExtensionItem[] items = new DOMExtensionItem[collection.size()]; |
| 105 | resultMap.values().toArray(items); |
csalter | 9b7e109 | 2006-07-29 04:02:26 +0000 | [diff] [blame] | 106 | |
| 107 | // here we sort the list alphabetically |
| 108 | // |
| 109 | if (items.length > 0) |
| 110 | { |
| 111 | Comparator comparator = new Comparator() |
| 112 | { |
| 113 | public int compare(Object arg0, Object arg1) |
| 114 | { |
| 115 | DOMExtensionItem a = (DOMExtensionItem)arg0; |
| 116 | DOMExtensionItem b = (DOMExtensionItem)arg1; |
| 117 | |
| 118 | // begin special case to ensure 'text nodes' come last |
| 119 | if (a.isTextValue() && !b.isTextValue()) |
| 120 | { |
| 121 | return 1; |
| 122 | } |
| 123 | else if (b.isTextValue() && !a.isTextValue()) |
| 124 | { |
| 125 | return -1; |
| 126 | } |
| 127 | // end special case |
| 128 | else |
| 129 | { |
| 130 | return Collator.getInstance().compare(a.getName(), b.getName()); |
| 131 | } |
| 132 | } |
| 133 | }; |
| 134 | Arrays.sort(items, comparator); |
| 135 | } |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 136 | return items; |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 137 | } |
| 138 | else if (input instanceof Attr) |
| 139 | { |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 140 | Attr attr = (Attr) input; |
csalter | 6b61eb0 | 2006-07-28 20:20:14 +0000 | [diff] [blame] | 141 | DOMExtensionItem item = DOMExtensionItem.createItemForAttributeText(attr.getOwnerElement(), attr); |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 142 | DOMExtensionItem[] items = {item}; |
| 143 | return items; |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 144 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 145 | return EMPTY_ARRAY; |
| 146 | } |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 147 | |
| 148 | public String getName(Object item) |
| 149 | { |
| 150 | if (item instanceof DOMExtensionItem) |
| 151 | { |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 152 | return ((DOMExtensionItem) item).getName(); |
| 153 | } |
kchong | 62c89ad | 2006-04-19 16:40:50 +0000 | [diff] [blame] | 154 | return ""; //$NON-NLS-1$ |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 155 | } |
| 156 | |
| 157 | public String getValue(Object item) |
| 158 | { |
| 159 | if (item instanceof DOMExtensionItem) |
| 160 | { |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 161 | return ((DOMExtensionItem) item).getValue(); |
| 162 | } |
kchong | 62c89ad | 2006-04-19 16:40:50 +0000 | [diff] [blame] | 163 | return ""; //$NON-NLS-1$ |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 164 | } |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 165 | |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 166 | public String[] getPossibleValues(Object item) |
| 167 | { |
| 168 | if (item instanceof DOMExtensionItem) |
| 169 | { |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 170 | return ((DOMExtensionItem) item).getPossibleValues(); |
| 171 | } |
| 172 | return EMPTY_STRING_ARRAY; |
| 173 | } |
| 174 | |
| 175 | protected void initPropertyEditorConfiguration(DOMExtensionItem item) |
| 176 | { |
| 177 | String namespace = item.getNamespace(); |
| 178 | String name = item.getName(); |
| 179 | String parentName = item.getParentName(); |
| 180 | NodeEditorConfiguration configuration = null; |
| 181 | if (namespace != null) |
| 182 | { |
| 183 | // TODO (cs) remove reference to XSDEditorPlugin... make generic |
| 184 | // perhaps push down the xml.ui ? |
| 185 | // |
csalter | 785c16c | 2006-05-16 21:49:50 +0000 | [diff] [blame] | 186 | NodeCustomizationRegistry registry = XSDEditorPlugin.getDefault().getNodeCustomizationRegistry(); |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 187 | NodeEditorProvider provider= registry.getNodeEditorProvider(namespace); |
| 188 | if (provider != null) |
| 189 | { |
csalter | 167ec9f | 2006-05-17 17:39:34 +0000 | [diff] [blame] | 190 | configuration = provider.getNodeEditorConfiguration(parentName, name); |
| 191 | if (configuration != null) |
| 192 | { |
| 193 | configuration.setParentNode(item.getParentNode()); |
| 194 | if (item.getNode() != null) |
| 195 | { |
| 196 | configuration.setNode(item.getNode()); |
| 197 | } |
| 198 | } |
csalter | df29c4e | 2006-05-16 21:43:16 +0000 | [diff] [blame] | 199 | } |
| 200 | } |
| 201 | String[] values = item.getPossibleValues(); |
| 202 | if (values != null && values.length > 1) |
| 203 | { |
| 204 | configuration = new DefaultListNodeEditorConfiguration(values); |
| 205 | } |
| 206 | |
| 207 | // Note that it IS expected that the configaration may be null |
| 208 | // |
| 209 | item.setPropertyEditorConfiguration(configuration); |
csalter | a28ae45 | 2006-04-16 22:04:44 +0000 | [diff] [blame] | 210 | } |
| 211 | } |