001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.schema;
011:
012: import java.io.PrintWriter;
013:
014: import org.eclipse.pde.internal.core.ischema.IMetaAttribute;
015: import org.eclipse.pde.internal.core.ischema.ISchema;
016: import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
017: import org.eclipse.pde.internal.core.ischema.ISchemaComplexType;
018: import org.eclipse.pde.internal.core.ischema.ISchemaCompositor;
019: import org.eclipse.pde.internal.core.ischema.ISchemaElement;
020: import org.eclipse.pde.internal.core.ischema.ISchemaObject;
021: import org.eclipse.pde.internal.core.ischema.ISchemaRepeatable;
022: import org.eclipse.pde.internal.core.ischema.ISchemaType;
023: import org.eclipse.pde.internal.core.util.SchemaUtil;
024: import org.eclipse.pde.internal.core.util.XMLComponentRegistry;
025:
026: public class SchemaElement extends RepeatableSchemaObject implements
027: ISchemaElement {
028:
029: private static final long serialVersionUID = 1L;
030:
031: public static final String P_ICON_NAME = "iconName"; //$NON-NLS-1$
032:
033: public static final String P_LABEL_PROPERTY = "labelProperty"; //$NON-NLS-1$
034:
035: public static final String P_TYPE = "type"; //$NON-NLS-1$
036:
037: private String labelProperty;
038:
039: private ISchemaType type;
040:
041: private String iconName;
042:
043: private boolean fTranslatable;
044:
045: private boolean fDeprecated;
046:
047: public SchemaElement(ISchemaObject parent, String name) {
048: super (parent, name);
049: }
050:
051: private String calculateChildRepresentation(ISchemaObject object,
052: boolean addLinks) {
053: String child = ""; //$NON-NLS-1$
054: if (object instanceof ISchemaCompositor) {
055: child = calculateCompositorRepresentation(
056: (ISchemaCompositor) object, addLinks);
057: if (!child.equals("EMPTY") && child.length() > 0) { //$NON-NLS-1$
058: child = "(" + child + ")"; //$NON-NLS-1$ //$NON-NLS-2$
059: }
060: } else {
061: child = object.getName();
062: if (addLinks) {
063: child = "<a href=\"#e." + child + "\">" + child + "</a>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
064: }
065: }
066: int minOccurs = 1;
067: int maxOccurs = 1;
068: if (object instanceof ISchemaRepeatable) {
069: minOccurs = ((ISchemaRepeatable) object).getMinOccurs();
070: maxOccurs = ((ISchemaRepeatable) object).getMaxOccurs();
071: }
072: if (minOccurs == 0) {
073: if (maxOccurs == 1)
074: child += "?"; //$NON-NLS-1$
075: else
076: child += "*"; //$NON-NLS-1$
077: } else if (minOccurs == 1) {
078: if (maxOccurs > 1)
079: child += "+"; //$NON-NLS-1$
080: }
081: return child;
082: }
083:
084: private String calculateCompositorRepresentation(
085: ISchemaCompositor compositor, boolean addLinks) {
086: int kind = compositor.getKind();
087: ISchemaObject[] children = compositor.getChildren();
088: if (children.length == 0)
089: return "EMPTY"; //$NON-NLS-1$
090: String text = kind == ISchemaCompositor.GROUP ? "(" : ""; //$NON-NLS-1$ //$NON-NLS-2$
091: for (int i = 0; i < children.length; i++) {
092: ISchemaObject object = children[i];
093: String child = calculateChildRepresentation(object,
094: addLinks);
095:
096: text += child;
097: if (i < children.length - 1) {
098: if (kind == ISchemaCompositor.SEQUENCE)
099: text += " , "; //$NON-NLS-1$
100: else if (kind == ISchemaCompositor.CHOICE)
101: text += " | "; //$NON-NLS-1$
102: }
103: }
104: if (kind == ISchemaCompositor.GROUP)
105: text += ")"; //$NON-NLS-1$
106: return text;
107: }
108:
109: public ISchemaAttribute getAttribute(String name) {
110: if (type != null && type instanceof ISchemaComplexType) {
111: return ((ISchemaComplexType) type).getAttribute(name);
112: }
113: return null;
114: }
115:
116: public int getAttributeCount() {
117: if (type != null && type instanceof ISchemaComplexType) {
118: return ((ISchemaComplexType) type).getAttributeCount();
119: }
120: return 0;
121: }
122:
123: public ISchemaAttribute[] getAttributes() {
124: if (type != null && type instanceof ISchemaComplexType) {
125: return ((ISchemaComplexType) type).getAttributes();
126: }
127: return new ISchemaAttribute[0];
128: }
129:
130: public String[] getAttributeNames() {
131: ISchemaAttribute[] attributes = getAttributes();
132: String[] names = new String[attributes.length];
133: for (int i = 0; i < attributes.length; i++)
134: names[i] = attributes[i].getName();
135: return names;
136: }
137:
138: public String getDTDRepresentation(boolean addLinks) {
139: String text = ""; //$NON-NLS-1$
140: if (type == null)
141: text += "EMPTY"; //$NON-NLS-1$
142: else {
143: if (type instanceof ISchemaComplexType) {
144: ISchemaComplexType complexType = (ISchemaComplexType) type;
145: ISchemaCompositor compositor = complexType
146: .getCompositor();
147: if (compositor != null)
148: text += calculateChildRepresentation(compositor,
149: addLinks);
150: else if (getAttributeCount() != 0)
151: text += "EMPTY"; //$NON-NLS-1$
152: }
153: if (text.length() == 0)
154: text += "(#PCDATA)"; //$NON-NLS-1$
155: }
156: if (text.length() > 0) {
157: if (!text.equals("EMPTY") && text.charAt(0) != '(') //$NON-NLS-1$
158: text = "(" + text + ")"; //$NON-NLS-1$ //$NON-NLS-2$
159: }
160: return text;
161: }
162:
163: public String getIconProperty() {
164: if (iconName != null)
165: return iconName;
166: ISchemaAttribute[] attributes = getAttributes();
167: for (int i = 0; i < attributes.length; i++) {
168: if (isValidIconProperty(attributes[i]))
169: return attributes[i].getName();
170: }
171: return null;
172: }
173:
174: public String getLabelProperty() {
175: if (labelProperty != null)
176: return labelProperty;
177: ISchemaAttribute[] attributes = getAttributes();
178: for (int i = 0; i < attributes.length; i++) {
179: if (isValidLabelProperty(attributes[i]))
180: return attributes[i].getName();
181: }
182: return null;
183: }
184:
185: private boolean isValidLabelProperty(ISchemaAttribute a) {
186: return a.getKind() == IMetaAttribute.STRING
187: && a
188: .getType()
189: .getName()
190: .equals(
191: ISchemaAttribute.TYPES[ISchemaAttribute.STR_IND])
192: && a.isTranslatable();
193: }
194:
195: private boolean isValidIconProperty(ISchemaAttribute a) {
196: return a.getKind() == IMetaAttribute.RESOURCE;
197: }
198:
199: public ISchemaType getType() {
200: return type;
201: }
202:
203: public void setParent(ISchemaObject parent) {
204: super .setParent(parent);
205: if (type != null) {
206: type.setSchema(getSchema());
207: if (type instanceof ISchemaComplexType) {
208: ISchemaComplexType ctype = (ISchemaComplexType) type;
209: ISchemaCompositor comp = ctype.getCompositor();
210: if (comp != null)
211: comp.setParent(this );
212: }
213: }
214: if (getAttributeCount() > 0) {
215: ISchemaAttribute[] atts = getAttributes();
216: for (int i = 0; i < atts.length; i++) {
217: ISchemaAttribute att = atts[i];
218: att.setParent(this );
219: }
220: }
221: }
222:
223: public void setIconProperty(String newIconName) {
224: String oldValue = iconName;
225: iconName = newIconName;
226: getSchema().fireModelObjectChanged(this , P_ICON_NAME, oldValue,
227: iconName);
228: }
229:
230: public void setTranslatableProperty(boolean translatable) {
231: boolean oldValue = fTranslatable;
232: fTranslatable = translatable;
233: getSchema().fireModelObjectChanged(this , P_TRANSLATABLE,
234: Boolean.valueOf(oldValue),
235: Boolean.valueOf(translatable));
236: }
237:
238: public void setDeprecatedProperty(boolean deprecated) {
239: boolean oldValue = fDeprecated;
240: fDeprecated = deprecated;
241: getSchema().fireModelObjectChanged(this , P_DEPRECATED,
242: Boolean.valueOf(oldValue), Boolean.valueOf(deprecated));
243: }
244:
245: public void setLabelProperty(String labelProperty) {
246: String oldValue = this .labelProperty;
247: this .labelProperty = labelProperty;
248: getSchema().fireModelObjectChanged(this , P_LABEL_PROPERTY,
249: oldValue, labelProperty);
250: }
251:
252: public void setType(ISchemaType newType) {
253: Object oldValue = type;
254: type = newType;
255: getSchema()
256: .fireModelObjectChanged(this , P_TYPE, oldValue, type);
257: }
258:
259: public void write(String indent, PrintWriter writer) {
260: writer.print(indent + "<element name=\"" + getName() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
261: ISchemaType type = getType();
262: if (type instanceof SchemaSimpleType) {
263: writer.print(" type=\"" + type.getName() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
264: }
265:
266: writer.println(">"); //$NON-NLS-1$
267: String indent2 = indent + Schema.INDENT;
268: String realDescription = getWritableDescription();
269: if (realDescription.length() == 0)
270: realDescription = null;
271: if (realDescription != null || iconName != null
272: || labelProperty != null || isDeprecated()
273: || hasTranslatableContent()) {
274: String indent3 = indent2 + Schema.INDENT;
275: String indent4 = indent3 + Schema.INDENT;
276: writer.println(indent2 + "<annotation>"); //$NON-NLS-1$
277: if (iconName != null || labelProperty != null
278: || isDeprecated() || hasTranslatableContent()) {
279: writer.println(indent3 + "<appInfo>"); //$NON-NLS-1$
280: writer.print(indent4 + "<meta.element"); //$NON-NLS-1$
281: if (labelProperty != null)
282: writer
283: .print(" labelAttribute=\"" + labelProperty + "\""); //$NON-NLS-1$ //$NON-NLS-2$
284: if (iconName != null)
285: writer.print(" icon=\"" + iconName + "\""); //$NON-NLS-1$ //$NON-NLS-2$
286: if (hasTranslatableContent())
287: writer.print(" translatable=\"true\""); //$NON-NLS-1$
288: if (isDeprecated())
289: writer.print(" deprecated=\"true\""); //$NON-NLS-1$
290: String extendedProperties = getExtendedAttributes();
291: if (extendedProperties != null)
292: writer.print(extendedProperties);
293: writer.println("/>"); //$NON-NLS-1$
294: writer.println(indent3 + "</appInfo>"); //$NON-NLS-1$
295: }
296: if (realDescription != null) {
297: writer.println(indent3 + "<documentation>"); //$NON-NLS-1$
298: if (getDescription() != null)
299: writer.println(indent4 + realDescription);
300: writer.println(indent3 + "</documentation>"); //$NON-NLS-1$
301: }
302: writer.println(indent2 + "</annotation>"); //$NON-NLS-1$
303: }
304:
305: if (type instanceof SchemaComplexType) {
306: SchemaComplexType complexType = (SchemaComplexType) type;
307: complexType.write(indent2, writer);
308: }
309: writer.println(indent + "</element>"); //$NON-NLS-1$
310: }
311:
312: /*
313: * (non-Javadoc)
314: *
315: * @see org.eclipse.pde.internal.core.ischema.IMetaElement#isTranslatable()
316: */
317: public boolean hasTranslatableContent() {
318: return fTranslatable;
319: }
320:
321: /* (non-Javadoc)
322: * @see org.eclipse.pde.internal.core.ischema.IMetaElement#isDeprecated()
323: */
324: public boolean isDeprecated() {
325: return fDeprecated;
326: }
327:
328: public String getExtendedAttributes() {
329: return null;
330: }
331:
332: public String getDescription() {
333: if (super .getDescription() != null) {
334: return super .getDescription();
335: }
336: ISchema schema = getSchema();
337: if ((schema == null) || (schema.getURL() == null)) {
338: // This can happen when creating a new extension point schema
339: return null;
340: }
341: String hashkey = schema.getURL().hashCode() + "_" + getName(); //$NON-NLS-1$
342: String description = XMLComponentRegistry.Instance()
343: .getDescription(hashkey,
344: XMLComponentRegistry.F_ELEMENT_COMPONENT);
345: if (description == null) {
346: SchemaElementHandler handler = new SchemaElementHandler(
347: getName());
348: SchemaUtil.parseURL(schema.getURL(), handler);
349: description = handler.getDescription();
350: XMLComponentRegistry.Instance().putDescription(hashkey,
351: description,
352: XMLComponentRegistry.F_ELEMENT_COMPONENT);
353: }
354:
355: return description;
356: }
357:
358: public int compareTo(Object arg0) {
359: if (arg0 instanceof ISchemaElement)
360: return getName().compareToIgnoreCase(
361: ((ISchemaElement) arg0).getName());
362: return -1;
363: }
364: }
|