/*******************************************************************************
* 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.meta.impl;
import org.w3c.dom.*;
import org.jboss.tools.common.meta.*;
import org.jboss.tools.common.meta.constraint.*;
import org.jboss.tools.common.model.*;
import org.jboss.tools.common.model.plugin.ModelPlugin;
import org.jboss.tools.common.model.util.*;
import org.jboss.tools.common.meta.constraint.impl.*;
public class XAttributeImpl extends XMetaElementImpl implements XAttribute {
private XModelEntity entity;
protected XAttributeEditor m_Editor;
protected String m_DefValue;
protected boolean m_Visible;
protected ConstraintHolder constraint = new ConstraintHolder(this);
protected boolean m_Required;
protected boolean m_Editable;
protected boolean trimmable;
protected boolean copyable;
protected String m_XMLName;
protected AdapterHolder adapter = new AdapterHolder();
public XAttributeImpl() {}
public XAttributeImpl copy() {
XAttributeImpl copy = new XAttributeImpl();
copy.name = name;
copy.displayName = displayName;
copy.p = p;
copy.m_Editor = m_Editor;
copy.m_DefValue = m_DefValue;
copy.m_Visible = m_Visible;
copy.constraint = constraint;
copy.m_Required = m_Required;
copy.m_Editable = m_Editable;
copy.trimmable = trimmable;
copy.copyable = copyable;
copy.m_XMLName = m_XMLName;
copy.adapter = adapter;
return copy;
}
public void valueChanged(XModelObject object) {
//// for (int i = 0; i < valuelisteners.length; i++)
//// valuelisteners[i].valueChanged(object, getName());
}
public XModelEntity getModelEntity() {
return entity;
}
void setModelEntity(XModelEntity entity) {
this.entity = entity;
}
public XAttributeEditor getEditor() {
return m_Editor;
}
void setEditor(XAttributeEditor ed) {
m_Editor = ed;
}
public String getDefaultValue() {
return m_DefValue;
}
public void setDefaultValue(String value) {
m_DefValue = replace(value, "%cr%", "\n"); //$NON-NLS-1$//$NON-NLS-2$
}
public boolean isTrimmable() {
return trimmable;
}
public boolean isCopyable() {
return copyable;
}
public boolean isVisible() {
return m_Visible;
}
void setVisible(boolean v) {
m_Visible = v;
}
public XAttributeConstraint getConstraint() {
return constraint.getConstraint();
}
public boolean isRequired() {
return m_Required;
}
void setRequired(boolean req) {
m_Required = req;
}
public boolean isEditable() {
return m_Editable;
}
void setEditable(boolean ed) {
m_Editable = ed;
}
void setXMLName(String xname) {
m_XMLName = xname;
}
public String getXMLName() {
return m_XMLName;
}
public boolean isFake() {
return "FAKE".equals(m_XMLName); //$NON-NLS-1$
}
public void load(Element el){
if(XMLUtil.getUniqueChild(el, EDITOR) == null) {
XAttributeEditorImpl editor = new XAttributeEditorImpl();
editor.setName(null);
setEditor(editor);
} else {
setEditor((XAttributeEditor)XMetaDataLoader.loadMetaElement(el, EDITOR, XAttributeEditorImpl.class, false));
}
Element c = XMetaDataLoader.getUniqueChild(el, CONSTRAINT);
if (c != null) loadConstraint(c);
setVisible(XMetaDataLoader.getBoolean(el, VISIBLE, true));
setRequired(XMetaDataLoader.getBoolean(el, REQUIRED, false));
setEditable(XMetaDataLoader.getBoolean(el, EDITABLE, false));
setDefaultValue(el.getAttribute(DEFAULT_VALUE));
setXMLName(el.getAttribute(XML_NAME));
loadAdapter(el);
trimmable = !XModelObjectConstants.NO.equals(el.getAttribute("TRIM")); //$NON-NLS-1$
copyable = !XModelObjectConstants.NO.equals(el.getAttribute("COPYABLE")); //$NON-NLS-1$
loadProperties(el);
}
public String toString(){
return getName();
}
public static final String LOADER = "loader"; //$NON-NLS-1$
public static final String CONSTRAINT_PREFIX =
"org.jboss.tools.common.meta.constraint.impl.XAttributeConstraint"; //$NON-NLS-1$
public static final String ATTRIBUTE_PREFIX =
"org.jboss.tools.common.meta.impl.adapters.XAdapter"; //$NON-NLS-1$
public void loadConstraint(Element element) {
if(element == null) return;
String loader = element.getAttribute(LOADER);
if(!XMetaDataLoader.hasAttribute(element, LOADER) || loader.trim().length() == 0) {
loader = ""; //$NON-NLS-1$
}
if(loader != null && loader.startsWith("%")) { //$NON-NLS-1$
loader = expand(loader, "AttributeConstraints"); //$NON-NLS-1$
}
constraint.init(loader, element);
}
public void loadAdapter(Element element) {
String loader = element.getAttribute(LOADER);
if(loader.length() == 0 && getXMLName().length() > 0) loader = "ModelElement"; //$NON-NLS-1$
adapter.init(this, loader, element);
loadValueListeners(element);
}
public XAdapter getAdapter() {
return adapter.getAdapter();
}
public void loadValueListeners(Element element) {
}
private static String replace(String source, String a, String b) {
if(source == null || source.indexOf(a) < 0) return source;
StringBuffer sb = new StringBuffer();
int i = 0, sL = source.length(), aL = a.length();
while(i < sL) {
int j = source.indexOf(a, i);
if(j < 0) {
sb.append(source.substring(i));
break;
}
sb.append(source.substring(i, j)).append(b);
i = j + aL;
}
return sb.toString();
}
}
class AdapterHolder {
private XAttributeImpl attribute;
private XAdapter adapter;
private String loader;
private Element element;
public AdapterHolder() {}
public void init(XAttributeImpl attribute, String loader, Element element) {
this.attribute = attribute;
this.loader = loader;
this.element = element;
adapter = null;
}
public XAdapter getAdapter() {
if(adapter != null) return adapter;
doGetAdapter();
if(adapter == null) adapter = new XAdapter();
return adapter;
}
private synchronized void doGetAdapter() {
String loader = this.loader;
Element element = this.element;
if(this.adapter != null) return;
XAdapter adapter = null;
if(loader == null || loader.length() == 0) {
adapter = new XAdapter();
} else {
String clsname = loader.indexOf('.') >= 0 ? loader : XAttributeImpl.ATTRIBUTE_PREFIX + loader;
try {
if(loader.length() > 0) {
adapter = (XAdapter)ModelFeatureFactory.getInstance().createFeatureInstance(clsname);
}
} catch (ClassCastException e) {
ModelPlugin.getPluginLog().logError("XAttributeImpl:loadAdapter:" + e.getMessage()); //$NON-NLS-1$
}
}
if(adapter == null) adapter = new XAdapter();
if(adapter != null) {
adapter.reload(element);
adapter.setConstraint(attribute.getConstraint());
}
loader = null;
this.element = null;
this.adapter = adapter;
}
}
class ConstraintHolder {
XAttributeImpl attribute;
private XAttributeConstraint constraint;
private String loader;
private Element element;
public ConstraintHolder(XAttributeImpl attribute) {
this.attribute = attribute;
}
public void init(String loader, Element element) {
this.loader = loader;
this.element = element;
constraint = null;
}
public XAttributeConstraint getConstraint() {
if(constraint == null) {
doGetConstraint();
if(constraint == null) constraint = new XAttributeConstraintImpl();
}
return constraint;
}
private void doGetConstraint() {
String loader = this.loader;
Element element = this.element;
if(this.constraint != null) return;
XAttributeConstraint constraint = null;
if(loader != null) try {
String clsname = loader.indexOf('.') >= 0 ? loader : XAttributeImpl.CONSTRAINT_PREFIX + loader;
if(loader.length() > 0) {
constraint = (XAttributeConstraint)ModelFeatureFactory.getInstance().createFeatureInstance(clsname);
}
} catch (ClassCastException e) {
ModelPlugin.getPluginLog().logError("XAttributeImpl:loadConstraint:" + e.getMessage(), e); //$NON-NLS-1$
}
if(constraint == null) constraint = new XAttributeConstraintImpl();
if(constraint instanceof XAttributeConstraintImpl) {
((XAttributeConstraintImpl)constraint).setAttribute(attribute);
}
if(element != null)
((XAttributeConstraintImpl)constraint).load(element);
loader = null;
element = null;
this.constraint = constraint;
}
}