1 /******************************************************************************* 2 * Copyright (c) 2000, 2016 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * David Carver - STAR - bug 213255 14 *******************************************************************************/ 15 package org.eclipse.pde.internal.core.schema; 16 17 import java.io.PrintWriter; 18 import org.eclipse.pde.internal.core.ischema.ISchema; 19 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute; 20 import org.eclipse.pde.internal.core.ischema.ISchemaElement; 21 import org.eclipse.pde.internal.core.ischema.ISchemaObject; 22 import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType; 23 import org.eclipse.pde.internal.core.util.SchemaUtil; 24 import org.eclipse.pde.internal.core.util.XMLComponentRegistry; 25 26 public class SchemaAttribute extends SchemaObject implements ISchemaAttribute { 27 28 private static final long serialVersionUID = 1L; 29 30 private int kind = STRING; 31 32 private int use = OPTIONAL; 33 34 private String valueFilter; 35 36 private ISchemaSimpleType type; 37 38 private String basedOn; 39 40 private Object value; 41 42 public static final String P_USE = "useProperty"; //$NON-NLS-1$ 43 44 public static final String P_VALUE_FILTER = "valueFilterProperty"; //$NON-NLS-1$ 45 46 public static final String P_VALUE = "value"; //$NON-NLS-1$ 47 48 public static final String P_KIND = "kindProperty"; //$NON-NLS-1$ 49 50 public static final String P_TYPE = "typeProperty"; //$NON-NLS-1$ 51 52 public static final String P_BASED_ON = "basedOnProperty"; //$NON-NLS-1$ 53 54 private boolean fTranslatable; 55 56 private boolean fDeprecated; 57 SchemaAttribute(ISchemaAttribute att, String newName)58 public SchemaAttribute(ISchemaAttribute att, String newName) { 59 super(att.getParent(), newName); 60 kind = att.getKind(); 61 use = att.getUse(); 62 value = att.getValue(); 63 type = new SchemaSimpleType(att.getType()); 64 basedOn = att.getBasedOn(); 65 } 66 SchemaAttribute(ISchemaObject parent, String name)67 public SchemaAttribute(ISchemaObject parent, String name) { 68 super(parent, name); 69 } 70 71 @Override getBasedOn()72 public String getBasedOn() { 73 if (getKind() == JAVA || getKind() == IDENTIFIER) { 74 return basedOn; 75 } 76 return null; 77 } 78 79 @Override getKind()80 public int getKind() { 81 return kind; 82 } 83 84 @Override getType()85 public ISchemaSimpleType getType() { 86 return type; 87 } 88 89 @Override getUse()90 public int getUse() { 91 return use; 92 } 93 94 @Override getValue()95 public Object getValue() { 96 return value; 97 } 98 getValueFilter()99 public String getValueFilter() { 100 return valueFilter; 101 } 102 setBasedOn(String newBasedOn)103 public void setBasedOn(String newBasedOn) { 104 String oldValue = basedOn; 105 basedOn = newBasedOn; 106 getSchema().fireModelObjectChanged(this, P_BASED_ON, oldValue, basedOn); 107 } 108 setKind(int newKind)109 public void setKind(int newKind) { 110 Integer oldValue = Integer.valueOf(kind); 111 kind = newKind; 112 getSchema().fireModelObjectChanged(this, P_KIND, oldValue, Integer.valueOf(kind)); 113 } 114 setTranslatableProperty(boolean translatable)115 public void setTranslatableProperty(boolean translatable) { 116 boolean oldValue = fTranslatable; 117 fTranslatable = translatable; 118 getSchema().fireModelObjectChanged(this, P_TRANSLATABLE, Boolean.valueOf(oldValue), Boolean.valueOf(translatable)); 119 } 120 setDeprecatedProperty(boolean deprecated)121 public void setDeprecatedProperty(boolean deprecated) { 122 boolean oldValue = fDeprecated; 123 fDeprecated = deprecated; 124 getSchema().fireModelObjectChanged(this, P_DEPRECATED, Boolean.valueOf(oldValue), Boolean.valueOf(deprecated)); 125 } 126 setType(ISchemaSimpleType newType)127 public void setType(ISchemaSimpleType newType) { 128 Object oldValue = type; 129 type = newType; 130 getSchema().fireModelObjectChanged(this, P_TYPE, oldValue, type); 131 } 132 133 @Override setParent(ISchemaObject obj)134 public void setParent(ISchemaObject obj) { 135 super.setParent(obj); 136 if (type != null) { 137 type.setSchema(getSchema()); 138 } 139 } 140 setUse(int newUse)141 public void setUse(int newUse) { 142 Integer oldValue = Integer.valueOf(use); 143 use = newUse; 144 getSchema().fireModelObjectChanged(this, P_USE, oldValue, Integer.valueOf(use)); 145 } 146 setValue(String value)147 public void setValue(String value) { 148 String oldValue = (String) this.value; 149 this.value = value; 150 getSchema().fireModelObjectChanged(this, P_VALUE, oldValue, value); 151 } 152 setValueFilter(String valueFilter)153 public void setValueFilter(String valueFilter) { 154 String oldValue = this.valueFilter; 155 this.valueFilter = valueFilter; 156 getSchema().fireModelObjectChanged(this, P_VALUE_FILTER, oldValue, valueFilter); 157 } 158 159 @Override write(String indent, PrintWriter writer)160 public void write(String indent, PrintWriter writer) { 161 boolean annotation = false; 162 ISchemaSimpleType type = getType(); 163 String typeName = type.getName(); 164 writer.print(indent); 165 writer.print("<attribute name=\"" + getName() + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 166 if (type.getRestriction() == null) { 167 writer.print(" type=\"" + typeName + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 168 } 169 String useString = null; 170 switch (getUse()) { 171 case OPTIONAL : 172 // don't write default setting 173 // useString="optional"; 174 break; 175 case DEFAULT : 176 useString = "default"; //$NON-NLS-1$ 177 break; 178 case REQUIRED : 179 useString = "required"; //$NON-NLS-1$ 180 break; 181 } 182 if (useString != null) { 183 writer.print(" use=\"" + useString + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 184 } 185 if (value != null && getUse() == DEFAULT) { 186 writer.print(" value=\"" + value + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 187 } 188 String documentation = getWritableDescription(); 189 if (documentation != null || this.getBasedOn() != null || getKind() != STRING) { 190 // Add annotation 191 annotation = true; 192 writer.println(">"); //$NON-NLS-1$ 193 String annIndent = indent + Schema.INDENT; 194 String indent2 = annIndent + Schema.INDENT; 195 String indent3 = indent2 + Schema.INDENT; 196 writer.print(annIndent); 197 writer.println("<annotation>"); //$NON-NLS-1$ 198 if (documentation != null) { 199 writer.println(indent2 + "<documentation>"); //$NON-NLS-1$ 200 writer.println(indent3 + documentation); 201 writer.println(indent2 + "</documentation>"); //$NON-NLS-1$ 202 } 203 if (getBasedOn() != null || getKind() != STRING || isDeprecated() || isTranslatable()) { 204 writer.println(indent2 + (getSchema().getSchemaVersion() >= 3.4 ? "<appinfo>" : "<appInfo>")); //$NON-NLS-1$ //$NON-NLS-2$ 205 writer.print(indent3 + "<meta.attribute"); //$NON-NLS-1$ 206 String kindValue = null; 207 switch (getKind()) { // TODO let's use some constants ;D 208 case JAVA : 209 kindValue = "java"; //$NON-NLS-1$ 210 break; 211 case RESOURCE : 212 kindValue = "resource"; //$NON-NLS-1$ 213 break; 214 case IDENTIFIER : 215 kindValue = "identifier"; //$NON-NLS-1$ 216 } 217 if (kindValue != null) { 218 writer.print(" kind=\"" + kindValue + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 219 } 220 if (getBasedOn() != null) { 221 writer.print(" basedOn=\"" + getBasedOn() + "\""); //$NON-NLS-1$ //$NON-NLS-2$ 222 } 223 if (isTranslatable()) { 224 writer.print(" translatable=\"true\""); //$NON-NLS-1$ 225 } 226 if (isDeprecated()) { 227 writer.print(" deprecated=\"true\""); //$NON-NLS-1$ 228 } 229 writer.println("/>"); //$NON-NLS-1$ 230 writer.println(indent2 + (getSchema().getSchemaVersion() >= 3.4 ? "</appinfo>" : "</appInfo>")); //$NON-NLS-1$ //$NON-NLS-2$ 231 } 232 writer.println(annIndent + "</annotation>"); //$NON-NLS-1$ 233 } 234 if (type.getRestriction() != null) { 235 type.write(indent + Schema.INDENT, writer); 236 } 237 if (annotation || type.getRestriction() != null) { 238 writer.println(indent + "</attribute>"); //$NON-NLS-1$ 239 } else { 240 writer.println("/>"); //$NON-NLS-1$ 241 } 242 } 243 244 @Override isTranslatable()245 public boolean isTranslatable() { 246 if (getKind() == STRING && fTranslatable) { 247 return type == null || "string".equals(type.getName()); //$NON-NLS-1$ 248 } 249 return false; 250 } 251 252 @Override isDeprecated()253 public boolean isDeprecated() { 254 return fDeprecated; 255 } 256 257 @Override getDescription()258 public String getDescription() { 259 if (super.getDescription() != null) { 260 return super.getDescription(); 261 } 262 ISchema schema = getSchema(); 263 if ((schema == null) || (schema.getURL() == null)) { 264 return null; 265 } 266 String elementName = null; 267 if (getParent() instanceof ISchemaElement) { 268 elementName = ((ISchemaElement) getParent()).getName(); 269 if (elementName == null) { 270 return null; 271 } 272 } 273 String hashkey = schema.getURL().toExternalForm().hashCode() + "_" + elementName + "_" + getName(); //$NON-NLS-1$ //$NON-NLS-2$ 274 String description = XMLComponentRegistry.Instance().getDescription(hashkey, XMLComponentRegistry.F_ATTRIBUTE_COMPONENT); 275 if (description == null) { 276 SchemaAttributeHandler handler = new SchemaAttributeHandler(elementName, getName()); 277 SchemaUtil.parseURL(schema.getURL(), handler); 278 description = handler.getDescription(); 279 XMLComponentRegistry.Instance().putDescription(hashkey, description, XMLComponentRegistry.F_ATTRIBUTE_COMPONENT); 280 } 281 282 return description; 283 } 284 285 } 286