/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.options.impl; import java.util.*; import org.jboss.tools.common.meta.*; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.impl.*; import org.jboss.tools.common.model.options.*; public class SharableElementImpl extends XModelObjectImpl implements SharableElement { private static final long serialVersionUID = 7922861006119791921L; private static final Map<String,String> singular = new HashMap<String,String>(3); static { singular.put("scope", "scope"); //$NON-NLS-1$ //$NON-NLS-2$ singular.put("sharing", "sharing"); //$NON-NLS-1$ //$NON-NLS-2$ } static boolean isSingular(String property) { return singular.get(property) != null; } protected XScope general_ = new XScope(GENERAL); protected XScope project_ = new XScope(PROJECT); protected Map<String,XScope> scopes = new HashMap<String,XScope>(); protected XScope scope = project_; private Map<String,SharableElement> children = new HashMap<String,SharableElement>(); private SharableComparator comparator = null; protected String name = ""; //$NON-NLS-1$ public SharableElementImpl() { super(); scopes.put(GENERAL, general_); scopes.put(PROJECT, project_); } public SharableElement getSharableParent() { Object p = getParent(); return (p instanceof SharableElement) ? (SharableElement)p : null; } public SharableElement[] getSharableChildren() { return children.values().toArray(new SharableElement[0]); } private int getChildrenCount(String entity) { SharableElement[] cs = getSharableChildren(); int k = 0; for (int i = 0; i < cs.length; i++) { if(entity.equals(cs[i].getModelEntity().getName())) ++k; } return k; } private void setScope0(String scopename) { scope = (XScope)scopes.get(scopename); if(scope == null) scope = project_; } public void setScope(String scopename) { setScope0(scopename); if(!scope.exists()) scope.setExists(true); } public String getScope() { return scope.getName(); } public boolean exists() { return general_.exists() || project_.exists(); } XScope getXScope(String scopename) { return (XScope)scopes.get(scopename); } public boolean scopeExists(String scopename) { XScope s = getXScope(scopename); return (s != null && s.exists()); } public void setScopeExists(String scopename, boolean b) { XScope s = getXScope(scopename); if(s == null || s.exists() == b || !XStudioLoaderPeer.instance().isScopeEditable(scopename)) return; setScopeExists0(scopename, b); } void setScopeExists0(String scopename, boolean b) { XScope s = getXScope(scopename); if(s == null || s.exists() == b) return; s.setExists(b); if(!b) { SharableElement[] cs = getSharableChildren(); for (int i = 0; i < cs.length; i++) { SharableElementImpl c = (SharableElementImpl)cs[i]; if(c != null) c.setScopeExists0(scopename, false); } } else { SharableElementImpl p = (SharableElementImpl)getSharableParent(); if(p != null) p.setScopeExists0(scopename, true); } } protected void onSetEntity(String entityName) { XModelEntity entity = getModel().getMetaData().getEntity(entityName); XAttribute[] as = entity.getAttributes(); for (int i = 0; i < LIST.length; i++) { scope = (XScope)scopes.get(LIST[i]); for (int j = 0; j < as.length; j++) { if(isSingular(as[j].getName())) continue; setAttributeValue(as[j].getName(), as[j].getDefaultValue()); } } comparator = new SharableComparator(entity.getChildren()); } ////////////////// children //////////////// public boolean addSharableChild(SharableElement child) { String childname = child.name(); if(findSharableChild(childname) != null) return false; children.put(childname, child); return true; } public void removeSharableChild(String name) { if(canRemoveChild(name)) { children.remove(name); } } public boolean canRemoveChild(String name) { SharableElementImpl s = (SharableElementImpl)children.get(name); if(s == null) return false; for (int i = 0; i < LIST.length; i++) { XScope sc = s.getXScope(LIST[i]); if(sc.exists() && !XStudioLoaderPeer.instance().isScopeEditable(LIST[i])) return false; } return true; } public SharableElement findSharableChild(String childname) { return (SharableElement)children.get(childname); } ////////////////// override //////////////// public String get(String name) { if("scope".equals(name)) { //$NON-NLS-1$ return getScope(); } else if("sharing".equals(name)) { //$NON-NLS-1$ String x = (general_.exists() ? GENERAL + "," : "") //$NON-NLS-1$ //$NON-NLS-2$ + (project_.exists() ? PROJECT + "," : ""); //$NON-NLS-1$ //$NON-NLS-2$ int c = x.length() - 1; return (c < 0) ? "" : x.substring(0, c); //$NON-NLS-1$ } return (XModelObjectConstants.XML_ATTR_NAME.equals(name)) ? name() : scope.getProperty(name); } public void set(String name, String value) { if("scope".equals(name)) { //$NON-NLS-1$ String ov = get(name); if(ov.equals(value)) return; String max = XStudioLoaderPeer.getMaxScope(ov, value); if(!XStudioLoaderPeer.instance().isScopeEditable(max)) return; setScope0(value); if(!scope.exists()) setScopeExists(scope.getName(), true); } else if("sharing".equals(name)) { //$NON-NLS-1$ setScopeExists(GENERAL, value.indexOf(GENERAL) >= 0); setScopeExists(PROJECT, value.indexOf(PROJECT) >= 0); } else if(XModelObjectConstants.XML_ATTR_NAME.equals(name)) { setName(value); } else { scope.setProperty(name, value); } } public String getAttributeValue(String name, String scopename) { XScope current = scope; setScope0(scopename); String res = getAttributeValue(name); scope = current; return res; } public String getDefaultValue(String name) { XAttribute a = getModelEntity().getAttribute(name); if(a == null) return null; if(a.getXMLName() == null || a.getXMLName().length() == 0) return a.getDefaultValue(); String v = getAttributeValue(name, GENERAL); if(v == null || v.length() == 0) v = a.getDefaultValue(); return v; } protected String getEntityName() { return "SharableDefault"; //$NON-NLS-1$ } public String name() { return name; } public void setName_0(String value) { name = value; } public boolean setName(String value) { if(value == null) return false; String oldvalue = name(); if(value.equals(oldvalue)) return true; SharableElement p = getSharableParent(); if(p != null && p.findSharableChild(value) != null) return false; if(p != null && p.findSharableChild(oldvalue) == null) return false; String op = getPath(); setName_0(value); if(p != null) { SharableElementImpl sp = (SharableElementImpl)p; sp.children.remove(oldvalue); sp.children.put(value, this); ((XModelImpl)getModel()).fireNodeChanged(this, op); fireUpdateChilds(); } return true; } protected void fireUpdateChilds() {} public boolean addChild_0(XModelObject child) { if(child == null) return false; boolean res = false; String ce = child.getModelEntity().getName(); XChild c_ent = getModelEntity().getChild(ce); if(c_ent == null) return false; if(c_ent.getMaxCount() < Integer.MAX_VALUE && getChildrenCount(ce) >= c_ent.getMaxCount()) { return false; } if(child instanceof SharableElement) { SharableElementImpl sc = (SharableElementImpl)child; res = addSharableChild(sc); if(res) { sc.setParent_0(this); for (int i = 0; i < LIST.length; i++) { if(sc.scopeExists(LIST[i])) { setScopeExists(LIST[i], true); } if(!scopeExists(LIST[i])) { ((XScope)sc.scopes.get(LIST[i])).setExists(false); } } } } return res; } public void removeChild_0(XModelObject o) { if(o instanceof SharableElement) { removeSharableChild(((SharableElement)o).name()); } } public XModelObject[] getChildren() { SharableElement[] cs = getSharableChildren(); Arrays.sort(cs, comparator); return cs; } public boolean isObjectEditable() { return isScopeEditable(scope.getName()); } public boolean isScopeEditable(String scopename) { return XStudioLoaderPeer.instance().isScopeEditable(scopename); } public boolean isScopeExists(String scopename) { XScope s = getXScope(scopename); return (s != null && s.exists()); } public boolean isAttributeEditable(String attributeName) { return isSingular(attributeName) || isObjectEditable(); } private void shareProperties0(XScope fs, XScope ts) { Properties fp = fs.properties(), tp = ts.properties(); Enumeration en = fp.keys(); while(en.hasMoreElements()) { String key = (String)en.nextElement(); String val = fp.getProperty(key); tp.setProperty(key, val); } } public void sharing(String fromscope, String toscope) { XScope fs = getXScope(fromscope), ts = getXScope(toscope); if(!ts.exists()) setScopeExists(toscope, true); if(!ts.exists()) return; shareProperties0(fs, ts); childsharing(fromscope, toscope); } protected void childsharing(String fromscope, String toscope) { ((XModelImpl)getModel()).fireNodeChanged(this, getPath()); } static String IMAGE_PROPERTY = "IMAGE"; public void merge(String fromscope, String toscope, boolean merge_all) { XScope fs = getXScope(fromscope), ts = getXScope(toscope); boolean existed = ts.exists(); if(!existed) setScopeExists(toscope, true); if(!ts.exists()) return; if(!existed || merge_all) { shareProperties0(fs, ts); } else if(fs.exists() && getModelEntity().getName().equals("SharableIcon") && GENERAL.equals(fromscope)) { String image = fs.getProperty(IMAGE_PROPERTY); String image2 = ts.getProperty(IMAGE_PROPERTY); if(image != null && !image.equals(image2)) { ts.setProperty(IMAGE_PROPERTY, image); } } mergeChildren(fromscope, toscope, existed, merge_all); setScope(PROJECT); } protected void mergeChildren(String fromscope, String toscope, boolean existed, boolean merge_all) { SharableElement[] cs = getSharableChildren(); for (int i = 0; i < cs.length; i++) ((SharableElementImpl)cs[i]).merge(fromscope, toscope, merge_all); } } class XScope { private String name; private Properties properties = new Properties(); private XModelObject child = null; private boolean exists = false; public XScope(String name) { this.name = name; } public String getName() { return name; } public String getProperty(String name) { return properties.getProperty(name); } public void setProperty(String name, String value) { properties.setProperty(name, value); } public boolean exists() { return exists; } public void setExists(boolean b) { exists = b; } public XModelObject getChild() { return child; } public void setChild(XModelObject child) { this.child = child; } Properties properties() { return properties; } } class SharableComparator implements Comparator<SharableElement> { private Hashtable<String,Integer> entities = null; public SharableComparator(XChild[] c) { entities = new Hashtable<String,Integer>(c.length); for (int i = 0; i < c.length; i++) { entities.put(c[i].getName(), Integer.valueOf(i * 100)); } } public int compare(SharableElement o1, SharableElement o2) { int i1 = getEntityRange(o1); int i2 = getEntityRange(o2); if(i1 != i2) return (i1 - i2) ; return o1.name().compareTo(o2.name()); } private int getEntityRange(SharableElement s) { Integer i = entities.get(s.getModelEntity().getName()); return (i == null) ? 1000 : i.intValue(); } public boolean equals(Object obj) { return obj == this; } }