1 11 12 package org.eclipse.pde.internal.ui.editor.contentassist; 13 14 import java.util.HashSet ; 15 16 import org.eclipse.core.resources.IProject; 17 import org.eclipse.core.resources.IResource; 18 import org.eclipse.core.runtime.CoreException; 19 import org.eclipse.osgi.util.NLS; 20 import org.eclipse.pde.core.IBaseModel; 21 import org.eclipse.pde.core.IIdentifiable; 22 import org.eclipse.pde.core.IModel; 23 import org.eclipse.pde.core.plugin.IPluginElement; 24 import org.eclipse.pde.core.plugin.IPluginExtension; 25 import org.eclipse.pde.core.plugin.IPluginObject; 26 import org.eclipse.pde.core.plugin.IPluginParent; 27 import org.eclipse.pde.internal.core.ischema.IMetaAttribute; 28 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute; 29 import org.eclipse.pde.internal.core.ischema.ISchemaComplexType; 30 import org.eclipse.pde.internal.core.ischema.ISchemaCompositor; 31 import org.eclipse.pde.internal.core.ischema.ISchemaElement; 32 import org.eclipse.pde.internal.core.ischema.ISchemaObject; 33 import org.eclipse.pde.internal.core.ischema.ISchemaRestriction; 34 import org.eclipse.pde.internal.core.ischema.ISchemaRootElement; 35 import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType; 36 import org.eclipse.pde.internal.core.ischema.ISchemaType; 37 import org.eclipse.pde.internal.core.schema.SchemaAttribute; 38 import org.eclipse.pde.internal.ui.PDEPlugin; 39 import org.eclipse.pde.internal.ui.PDEUIMessages; 40 import org.eclipse.pde.internal.ui.editor.text.XMLUtil; 41 42 46 public class XMLInsertionComputer { 47 48 52 public static void computeInsertion(ISchemaElement sElement, 53 IPluginParent pElement) { 54 HashSet visited = new HashSet (); 55 if ((sElement == null) || 56 (pElement == null)) { 57 return; 60 } 61 visited.add(sElement.getName()); 62 try { 64 computeInsertionParent(sElement, pElement, visited); 65 } catch (CoreException e) { 66 PDEPlugin.logException(e); 68 } 69 } 70 71 77 protected static void computeInsertionParent(ISchemaElement sElement, 78 IPluginParent pElement, HashSet visited) throws CoreException { 79 if (isSingleZeroElementEdgeCase(sElement, pElement)) { 81 computeInsertionZeroElementEdgeCase(sElement, pElement, visited); 83 } else { 84 computeInsertionType(sElement, pElement, visited); 86 } 87 } 88 89 104 protected static void computeInsertionZeroElementEdgeCase( 105 ISchemaElement sElement, IPluginParent pElement, HashSet visited) 106 throws CoreException { 107 computeInsertionAllAttributes(pElement, sElement); 112 ISchemaCompositor compositor = 114 ((ISchemaComplexType)sElement.getType()).getCompositor(); 115 ISchemaElement childSchemaElement = 118 (ISchemaElement)compositor.getChildren()[0]; 119 IPluginElement childElement = createElement(pElement, childSchemaElement); 122 visited.add(childSchemaElement.getName()); 124 computeInsertionType(childSchemaElement, childElement, visited); 126 pElement.add(childElement); 129 } 130 131 136 protected static boolean isSingleZeroElementEdgeCase(ISchemaElement sElement, 137 IPluginParent pElement) { 138 if ((sElement.getType() instanceof ISchemaComplexType) && 140 (pElement instanceof IPluginExtension)) { 141 ISchemaCompositor compositor = 144 ((ISchemaComplexType)sElement.getType()).getCompositor(); 145 if ((compositor == null) || 148 (isSequenceCompositor(compositor) == false) || 149 (compositor.getChildCount() != 1) || 150 (compositor.getMinOccurs() != 1)) { 151 return false; 152 } 153 ISchemaObject schemaObject = compositor.getChildren()[0]; 157 if ((schemaObject instanceof ISchemaElement) == false) { 159 return false; 160 } 161 ISchemaElement schemaElement = (ISchemaElement)schemaObject; 163 if (schemaElement.getMinOccurs() == 0) { 165 return true; 166 } 167 } 168 return false; 169 } 170 171 177 protected static void computeInsertionType(ISchemaElement sElement, 178 IPluginParent pElement, HashSet visited) throws CoreException { 179 180 if ((sElement == null) || 181 (pElement == null)) { 182 return; 185 } else if (sElement.getType() instanceof ISchemaSimpleType) { 186 try { 189 if (pElement instanceof IPluginElement) 190 ((IPluginElement)pElement).setText(NLS.bind( 191 PDEUIMessages.XMLCompletionProposal_InfoElement, 192 pElement.getName())); 193 } catch (CoreException e) { 194 PDEPlugin.logException(e); 195 } 196 return; 197 } else if (sElement.getType() instanceof ISchemaComplexType) { 198 computeInsertionAllAttributes(pElement, sElement); 202 ISchemaCompositor compositor = 204 ((ISchemaComplexType)sElement.getType()).getCompositor(); 205 computeInsertionSequence(compositor, pElement, visited); 207 } else { 208 return; 210 } 211 } 212 213 219 protected static void computeInsertionObject(IPluginParent pElement, 220 HashSet visited, ISchemaObject schemaObject) throws CoreException { 221 if (schemaObject instanceof ISchemaElement) { 222 ISchemaElement schemaElement = (ISchemaElement) schemaObject; 223 computeInsertionElement(pElement, visited, schemaElement); 224 } else if (schemaObject instanceof ISchemaCompositor) { 225 ISchemaCompositor sCompositor = (ISchemaCompositor) schemaObject; 226 computeInsertionSequence(sCompositor, pElement, visited); 227 } else { 228 } 230 } 231 232 236 protected static boolean isSequenceCompositor(ISchemaCompositor compositor) { 237 if (compositor == null) { 238 return false; 239 } else if (compositor.getKind() == ISchemaCompositor.CHOICE) { 240 return false; 244 } else if (compositor.getKind() == ISchemaCompositor.ALL) { 245 return false; 247 } else if (compositor.getKind() == ISchemaCompositor.GROUP) { 248 return false; 250 } else if (compositor.getKind() == ISchemaCompositor.SEQUENCE) { 251 return true; 252 } else { 253 return false; 255 } 256 } 257 258 264 protected static void computeInsertionElement(IPluginParent pElement, 265 HashSet visited, ISchemaElement schemaElement) throws CoreException { 266 for (int j = 0; j < schemaElement.getMinOccurs(); j++) { 267 IPluginElement childElement = createElement(pElement, schemaElement); 269 HashSet newSet = (HashSet ) visited.clone(); 271 if (newSet.add(schemaElement.getName())) { 272 computeInsertionType(schemaElement, childElement, newSet); 273 } else { 274 childElement.setText( 275 PDEUIMessages.XMLCompletionProposal_ErrorCycle); 276 } 277 pElement.add(childElement); 280 } 281 } 282 283 291 protected static IPluginElement createElement(IPluginParent pElement, 292 ISchemaElement schemaElement) throws CoreException { 293 IPluginElement childElement = null; 294 childElement = 295 pElement.getModel().getFactory().createElement(pElement); 296 childElement.setName(schemaElement.getName()); 297 return childElement; 298 } 299 300 305 protected static void computeInsertionAllAttributes(IPluginParent pElement, 306 ISchemaElement sElement) { 307 ISchemaComplexType type = (ISchemaComplexType)sElement.getType(); 309 IResource resource = pElement.getModel().getUnderlyingResource(); 311 IProject project = null; 312 if (resource != null) 313 project = resource.getProject(); 314 ISchemaAttribute[] attributes = type.getAttributes(); 316 int counter = XMLUtil.getCounterValue(sElement); 318 for (int i = 0; i < type.getAttributeCount(); i++) { 320 ISchemaAttribute attribute = attributes[i]; 321 try { 324 if (attribute.getUse() == ISchemaAttribute.REQUIRED) { 325 String value = generateAttributeValue(project, counter, attribute); 326 setAttribute(pElement, attribute.getName(), value, counter); 328 } 329 } catch (CoreException e) { 331 PDEPlugin.logException(e); 332 } 333 } 334 } 335 336 342 protected static String generateAttributeValue(IProject project, 343 int counter, ISchemaAttribute attribute) { 344 String value = ""; ISchemaRestriction restriction = 346 attribute.getType().getRestriction(); 347 348 if (attribute.getKind() == IMetaAttribute.JAVA && 349 project != null) { 350 value = XMLUtil.createDefaultClassName(project, 352 attribute, counter); 353 } else if (restriction != null) { 354 value = restriction.getChildren()[0].toString(); 359 } else if ((attribute instanceof SchemaAttribute) && 360 ((SchemaAttribute)attribute).isTranslatable()) { 361 value = attribute.getName(); 364 } else if (project != null) { 365 value = XMLUtil.createDefaultName(project, 368 attribute, counter); 369 } 370 return value; 371 } 372 373 public static String generateAttributeValue(ISchemaAttribute attribute, 374 IBaseModel baseModel, String defaultValue) { 375 if (baseModel instanceof IModel) { 376 IResource resource = ((IModel)baseModel).getUnderlyingResource(); 377 if (resource != null) { 378 int counter = 1; 379 if (attribute.getParent() instanceof ISchemaElement) { 380 ISchemaElement sElement = (ISchemaElement)attribute.getParent(); 381 if (sElement instanceof ISchemaRootElement) { 382 return defaultValue; 387 } 388 counter = XMLUtil.getCounterValue(sElement); 390 } 391 return generateAttributeValue(resource.getProject(), counter, attribute); 392 } 393 } 394 return defaultValue; 395 } 396 397 402 protected static void computeInsertionSequence(ISchemaCompositor compositor, 403 IPluginParent pElement, HashSet visited) throws CoreException { 404 if (compositor == null) 405 return; 406 for (int k = 0; k < compositor.getMinOccurs(); k++) { 408 if (isSequenceCompositor(compositor) == false) 410 continue; 411 ISchemaObject[] schemaObject = compositor.getChildren(); 413 for (int i = 0; i < compositor.getChildCount(); i++) { 415 computeInsertionObject(pElement, visited, schemaObject[i]); 416 } 417 } 418 } 419 420 427 protected static void setAttribute(IPluginParent parent, String attName, 428 String attValue, int counter) throws CoreException { 429 if (parent instanceof IPluginElement) { 430 ((IPluginElement)parent).setAttribute(attName, attValue); 431 } else if (parent instanceof IPluginExtension) { 432 IPluginExtension pe = (IPluginExtension)parent; 433 if (attName.equals(IIdentifiable.P_ID)) { 434 String currValue = pe.getId(); 435 if (currValue == null || currValue.length() == 0) { 438 pe.setId(attName + counter); 441 } 442 } else if (attName.equals(IPluginObject.P_NAME)) { 443 String currValue = pe.getName(); 444 if (currValue == null || currValue.length() == 0) 445 pe.setName(attName); 446 } else if (attName.equals(IPluginExtension.P_POINT)) { 447 String currValue = pe.getPoint(); 448 if (currValue == null || currValue.length() == 0) 449 pe.setPoint(attValue); 450 } 451 } 452 } 453 454 public static boolean hasOptionalAttributes(ISchemaElement ele) { 455 ISchemaAttribute[] attrs = ele.getAttributes(); 456 for (int i = 0; i < attrs.length; i++) 457 if (attrs[i].getUse() == ISchemaAttribute.OPTIONAL || 458 attrs[i].getUse() == ISchemaAttribute.DEFAULT) 459 return true; 460 return false; 461 } 462 463 public static boolean hasOptionalChildren(ISchemaObject obj, boolean onChild, HashSet set) { 464 if (obj == null || set.contains(obj)) 465 return false; 466 set.add(obj); 467 if (obj instanceof ISchemaElement) { 468 if (onChild 469 && ((ISchemaElement)obj).getMinOccurs() == 0 470 && ((ISchemaElement)obj).getMaxOccurs() > 0) 471 return true; 472 ISchemaType type = ((ISchemaElement) obj).getType(); 473 if (type instanceof ISchemaComplexType) 474 return hasOptionalChildren(((ISchemaComplexType)type).getCompositor(), true, set); 475 } else if (obj instanceof ISchemaCompositor) { 476 ISchemaObject[] children = ((ISchemaCompositor)obj).getChildren(); 477 if (children != null) 478 for (int i = 0; i < children.length; i++) 479 if (hasOptionalChildren(children[i], true, set)) 480 return true; 481 } 482 return false; 483 } 484 485 } 486 | Popular Tags |