Index: src/org/jboss/tools/common/meta/constraint/impl/XAttributeConstraintInt.java =================================================================== --- src/org/jboss/tools/common/meta/constraint/impl/XAttributeConstraintInt.java (revision 22035) +++ src/org/jboss/tools/common/meta/constraint/impl/XAttributeConstraintInt.java (working copy) @@ -14,7 +14,7 @@ import org.w3c.dom.*; public class XAttributeConstraintInt extends XAttributeConstraintProperties { - protected boolean mandatory = true; + protected boolean mandatory = false; protected int min = Integer.MIN_VALUE; protected int max = Integer.MAX_VALUE; public XAttributeConstraintInt() { @@ -23,7 +23,7 @@ public void load(Element element) { super.load(element); - mandatory = getBoolean("mandatory", true); //$NON-NLS-1$ + mandatory = getBoolean("mandatory", false); //$NON-NLS-1$ min = getInt("minimum", Integer.MIN_VALUE); //$NON-NLS-1$ max = getInt("maximum", Integer.MAX_VALUE); //$NON-NLS-1$ } Index: src/org/jboss/tools/common/model/engines/impl/EnginesLoader.java =================================================================== --- src/org/jboss/tools/common/model/engines/impl/EnginesLoader.java (revision 22035) +++ src/org/jboss/tools/common/model/engines/impl/EnginesLoader.java (working copy) @@ -86,11 +86,18 @@ c = cs[i].copy(); object.addChild(c); } else { - boolean has_id = c.getModelEntity().getAttribute(XModelObjectLoaderUtil.ATTR_ID_NAME) != null; + boolean has_id = c.getModelEntity().getAttribute(XModelObjectLoaderUtil.ATTR_ID_NAME) != null + || ((XModelObjectImpl)c).hasIdAttr(); if(has_id) { c.removeFromParent(); EnginesLoader.merge(c, cs[i], false); - object.addChild(c); + if(!object.addChild(c)) { + c.set(XModelObjectImpl.DUPLICATE, "1234"); + object.addChild(c); + } + if(c.get(XModelObjectImpl.DUPLICATE) != null) { + c.set(XModelObjectImpl.DUPLICATE, ""); + } } else { EnginesLoader.merge(c, cs[i], fire); } Index: src/org/jboss/tools/common/model/markers/ConstraintChecker.java =================================================================== --- src/org/jboss/tools/common/model/markers/ConstraintChecker.java (revision 22035) +++ src/org/jboss/tools/common/model/markers/ConstraintChecker.java (working copy) @@ -39,12 +39,19 @@ private void check(XModelObject o) { XAttribute[] as = o.getModelEntity().getAttributes(); + String idAttr = null; for (int i = 0; i < as.length; i++) { String error = as[i].getConstraint().getError(o.getAttributeValue(as[i].getName())); if(error != null) addProblem(o, as[i].getName(), "Value " + error); + if("true".equals(as[i].getProperty("id"))) idAttr = as[i].getName(); } XModelObject[] cs = ((XModelObjectImpl)o).getLoadedChildren(); for (int i = 0; i < cs.length; i++) check(cs[i]); + + String duplicate = o.get(XModelObjectImpl.DUPLICATE); + if(duplicate != null && duplicate.length() > 0 && idAttr != null) { + addProblem(o, idAttr, "Value " + o.getAttributeValue(idAttr) + " is not unique."); + } } protected void addProblem(XModelObject o, String attr, String msg) { Index: src/org/jboss/tools/common/model/markers/ResourceMarkers.java =================================================================== --- src/org/jboss/tools/common/model/markers/ResourceMarkers.java (revision 22035) +++ src/org/jboss/tools/common/model/markers/ResourceMarkers.java (working copy) @@ -30,7 +30,7 @@ public class ResourceMarkers { public static String TEXT_PROBLEM = "org.jboss.tools.common.model.textproblemmarker"; //$NON-NLS-1$ - public static String CONSTRAINT_PROBLEM = "org.jboss.tools.common.model.web.ui.constraintsmarker"; //$NON-NLS-1$ + public static String CONSTRAINT_PROBLEM = "org.jboss.tools.jst.web.ui.constraintsmarker"; //$NON-NLS-1$ public static String JST_WEB_PROBLEM = "org.jboss.tools.jst.web.ui.strutsmarker"; //$NON-NLS-1$ private XModelObject object; Index: src/org/jboss/tools/common/model/util/XModelObjectLoaderUtil.java =================================================================== --- src/org/jboss/tools/common/model/util/XModelObjectLoaderUtil.java (revision 22035) +++ src/org/jboss/tools/common/model/util/XModelObjectLoaderUtil.java (working copy) @@ -223,9 +223,13 @@ XModelEntity entity = o.getModelEntity(); XAttribute[] as = entity.getAttributes(); for (int i = 0; i < as.length; i++) { + String n = as[i].getName(); + if("attributes".equals(n) && "true".equals(as[i].getProperty("any"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + loadAnyAtributes(element, o); + continue; + } String xmlname = as[i].getXMLName(); if (xmlname == null || xmlname.length() == 0) continue; - String n = as[i].getName(); String value = getAttribute(element, xmlname, as[i]); if (value != null) o.setAttributeValue(n, value); String commentName = getAttributeCommentName(xmlname); @@ -332,6 +336,17 @@ if(q != null) EnginesLoader.merge(q, co, false); } catch (XModelException exc) { ModelPlugin.getPluginLog().logError("XModelObjectLoaderUtil:loadChildren:" + exc.getMessage(), exc); //$NON-NLS-1$ + } else { + int k = 1; + String pp = co.getPathPart(); + while(o.getChildByPath(pp) != null) { + co.set(XModelObjectImpl.DUPLICATE, "" + k); //$NON-NLS-1$ + String ppn = co.getPathPart(); + if(ppn.equals(pp)) break; + pp = ppn; + ++k; + } + o.addChild(co); } continue; } @@ -443,9 +458,13 @@ } for (int i = 0; i < as.length; i++) { if (as[i].isFake()) continue; + String n = as[i].getName(); + if("attributes".equals(n) && "true".equals(as[i].getProperty("any"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + saveAnyAtributes(element, o); + continue; + } String xmlname = as[i].getXMLName(); if (xmlname == null || xmlname.length() == 0) continue; - String n = as[i].getName(); String v = o.getAttributeValue(n); if (isSaveable(entity, n, v, as[i].getDefaultValue())) { saveAttribute(element, xmlname, v); @@ -843,6 +862,23 @@ protected void loadAnyElement(Element element, XModelObject o) { o.setAttributeValue("tag", element.getTagName()); //$NON-NLS-1$ + loadAnyAtributes(element, o); + String text = getAttribute(element, "#text").trim(); //$NON-NLS-1$ + if(text.length() > 0) { + while(text.startsWith("\n") || text.startsWith("\r")) text = text.substring(1); //$NON-NLS-1$ //$NON-NLS-2$ + while(text.endsWith("\n") || text.endsWith("\r")) text = text.substring(0, text.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$ + o.setAttributeValue("text", text); //$NON-NLS-1$ + } + loadChildren(element, o); + } + + public static void loadAnyAtributes(Element element, XModelObject o) { + HashSet attrs = new HashSet(); + XAttribute[] oas = o.getModelEntity().getAttributes(); + for (XAttribute a: oas) { + String xml = a.getXMLName(); + if(xml != null && xml.length() > 0) attrs.add(xml); + } StringBuffer sb = new StringBuffer(); NamedNodeMap as = element.getAttributes(); for (int i = 0; i < as.getLength(); i++) { @@ -848,6 +884,7 @@ for (int i = 0; i < as.getLength(); i++) { Node n = as.item(i); String nm = n.getNodeName(); + if(attrs.contains(nm)) continue; String v = n.getNodeValue(); if(v == null) continue; if(sb.length() > 0) sb.append(";"); //$NON-NLS-1$ @@ -854,13 +891,6 @@ sb.append(nm).append("=").append(v); //$NON-NLS-1$ } o.setAttributeValue("attributes", sb.toString()); //$NON-NLS-1$ - String text = getAttribute(element, "#text").trim(); //$NON-NLS-1$ - if(text.length() > 0) { - while(text.startsWith("\n") || text.startsWith("\r")) text = text.substring(1); //$NON-NLS-1$ //$NON-NLS-2$ - while(text.endsWith("\n") || text.endsWith("\r")) text = text.substring(0, text.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$ - o.setAttributeValue("text", text); //$NON-NLS-1$ - } - loadChildren(element, o); } protected void saveAnyElement(Element parent, XModelObject o) { @@ -870,6 +900,18 @@ xmlname = namespace + ":" + xmlname; //$NON-NLS-1$ } Element element = XMLUtil.createElement(parent, xmlname); + saveAnyAtributes(element, o); + String text = o.getAttributeValue("text"); //$NON-NLS-1$ + if(text != null && text.length() > 0) { + saveAttribute(element, "#text", text); //$NON-NLS-1$ + } + XModelObject[] cs = o.getChildren(); + for (int i = 0; i < cs.length; i++) { + saveAnyElement(element, cs[i]); + } + } + + public static void saveAnyAtributes(Element element, XModelObject o) { String attrs = o.getAttributeValue("attributes"); //$NON-NLS-1$ StringTokenizer st = new StringTokenizer(attrs, ";"); //$NON-NLS-1$ while(st.hasMoreTokens()) { @@ -880,14 +922,6 @@ String v = t.substring(i + 1); element.setAttribute(n, v); } - String text = o.getAttributeValue("text"); //$NON-NLS-1$ - if(text != null && text.length() > 0) { - saveAttribute(element, "#text", text); //$NON-NLS-1$ - } - XModelObject[] cs = o.getChildren(); - for (int i = 0; i < cs.length; i++) { - saveAnyElement(element, cs[i]); - } } protected void eitherOr(Element element, String attr1, String attr2) { @@ -941,6 +975,9 @@ } } mergeFinalComment(destination, source, fire); + + String d = destination.get(XModelObjectImpl.DUPLICATE); + if(d != null && d.length() > 0) destination.set(XModelObjectImpl.DUPLICATE, ""); } public static void mergeAttributeComment(XModelObject destination, XModelObject source, XAttribute attr, boolean fire) { Index: src/org/jboss/tools/common/model/impl/XModelObjectImpl.java =================================================================== --- src/org/jboss/tools/common/model/impl/XModelObjectImpl.java (revision 22035) +++ src/org/jboss/tools/common/model/impl/XModelObjectImpl.java (working copy) @@ -40,6 +40,7 @@ public class XModelObjectImpl implements XModelObject, Serializable, Cloneable { private static final long serialVersionUID = 3860648580262144825L; // protected static final String ENTITY = XModelConstants.XMODEL_ENTITY_ATTR; + public static final String DUPLICATE = "__duplicate"; private XModel model = null; private XModelEntity entity = null; private XModelObjectImpl parent = null; @@ -136,6 +137,21 @@ properties.put(name.intern(), value); } + private Boolean hasIdAttr = null; + + public boolean hasIdAttr() { + if(hasIdAttr != null) return hasIdAttr.booleanValue(); + hasIdAttr = Boolean.FALSE; + for (int i = 0; i < getModelEntity().getAttributes().length; i++) { + if("true".equals(getModelEntity().getAttributes()[i].getProperty("id"))) { + hasIdAttr = Boolean.TRUE; + break; + } + } + + return hasIdAttr.booleanValue(); + } + protected String get_0(String name) { XAttribute a = getModelEntity().getAttribute(name); return (a == null || a.getAdapter() == null) ? null : a.getAdapter().getProperty(this); @@ -300,7 +316,16 @@ public String getPathPart() { String p = name(); - return (p == null || p.indexOf('/') < 0) ? p : p.replace('/', '#'); + p = ((p == null || p.indexOf('/') < 0) ? p : p.replace('/', '#')); + return applyDuplicate(p); + } + + protected final String applyDuplicate(String pathpart) { + String duplicate = get(DUPLICATE); + return (duplicate == null || duplicate.length() == 0) + ? pathpart + : pathpart + DUPLICATE + duplicate; + } public XModelObject getChildByPath(String path) { @@ -360,6 +385,10 @@ String entity = (transform) ? getEntityForCopy() : getModelEntity().getName(); XModelObject c = getModel().createModelObject(entity, p); if(c != null) c.setModified(true); + String d = get(DUPLICATE); + if(d != null && d.length() > 0) { + c.set(DUPLICATE, d); + } return c; } Index: src/org/jboss/tools/common/model/impl/RegularObjectImpl.java =================================================================== --- src/org/jboss/tools/common/model/impl/RegularObjectImpl.java (revision 22035) +++ src/org/jboss/tools/common/model/impl/RegularObjectImpl.java (working copy) @@ -117,6 +117,18 @@ k++; } return; + } else if(hasIdAttr()) { + int k = 1; + while(c != null) { + super.set(XModelObjectImpl.DUPLICATE, "" + k); //$NON-NLS-1$ + npp = getPathPart(); + if(k == 1 && npp.indexOf(XModelObjectImpl.DUPLICATE) < 0) { + elementExists(c, name, value); + return; + } + c = p.children.change(this, opp, npp); + k++; + } } else { if(ov == null) properties.remove(name); else super.set(name, ov); elementExists(c, name, value);