blob: 5e173bd499954a838e8adf4876ccec81369ebb64 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2012 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.meta;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.common.utils.ExtensionHelper;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.meta.internal.ModifiedTypeMetaImpl;
import org.eclipse.epf.library.edit.meta.internal.TypeDefParserImpl;
import org.eclipse.epf.library.edit.uma.DescriptorExt;
import org.eclipse.epf.library.edit.uma.MethodElementExt;
import org.eclipse.epf.library.edit.uma.MethodElementExt.WorkProductStateExt;
import org.eclipse.epf.library.edit.uma.MethodPluginExt;
import org.eclipse.epf.library.edit.util.DebugUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.PracticePropUtil;
import org.eclipse.epf.library.edit.util.PropUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Constraint;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.util.ExtendedAttribute;
import org.eclipse.epf.uma.util.ExtendedReference;
import org.eclipse.epf.uma.util.MetaElement;
import org.eclipse.epf.uma.util.ModifiedTypeMeta;
import org.eclipse.epf.uma.util.QualifiedReference;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.epf.uma.util.UserDefinedTypeMeta;
/**
* @author Weiping Lu
*/
public class TypeDefUtil {
private static TypeDefUtil instance;
static {
Object obj = ExtensionHelper.create(TypeDefUtil.class, null);
if (obj instanceof TypeDefUtil) {
instance = (TypeDefUtil) obj;
} else {
instance = new TypeDefUtil();
}
}
public static TypeDefUtil getInstance() {
return instance;
}
protected TypeDefUtil() {
}
public TypeDefParser getTypeDefParser() {
return new TypeDefParserImpl();
}
public IMetaDef createMetaDef(Class cls) {
if (cls == ModifiedTypeMeta.class) {
return (ModifiedTypeMetaImpl) newModifiedTypeMeta();
}
return null;
}
public void associate(ExtendedReference eRef, EReference ref) {
associate_(eRef, ref);
}
public void associate(ExtendedAttribute eAtt, EAttribute att) {
associate_(eAtt, att);
}
private void associate_(MetaElement metaElement, EStructuralFeature feature) {
if (! (metaElement instanceof Adapter)) {
return;
}
int sz = feature.eAdapters().size();
for (int i = sz - 1; i >=0; i--) {
Object adapter = feature.eAdapters().get(i);
if (adapter instanceof MetaElement) {
feature.eAdapters().remove(i);
}
}
feature.eAdapters().add((Adapter) metaElement);
}
public ExtendedReference getAssociatedExtendedReference(EStructuralFeature feature) {
MetaElement element = getAssociatedMetaElement(feature);
if (element instanceof ExtendedReference) {
return (ExtendedReference) element;
}
return null;
}
public ExtendedAttribute getAssociatedExtendedAttribute(EStructuralFeature feature) {
MetaElement element = getAssociatedMetaElement(feature);
if (element instanceof ExtendedAttribute) {
return (ExtendedAttribute) element;
}
return null;
}
private MetaElement getAssociatedMetaElement(EStructuralFeature feature) {
if (feature == null) {
return null;
}
for (Object adapter : feature.eAdapters()) {
if (adapter instanceof MetaElement) {
return (MetaElement) adapter;
}
}
return null;
}
public Object eGet(EObject obj, EStructuralFeature feature) {
return eGet(obj, feature, false);
}
public Object eGet(EObject obj, EStructuralFeature feature, boolean toModify) {
try {
return eGet_(obj, feature, toModify);
} catch (Throwable e) {
LibraryEditPlugin.getDefault().getLogger().logError(e);
if (DebugUtil.udtDebug || DebugUtil.uiDebug) {
e.printStackTrace();
}
}
boolean isMany = false;
if (feature instanceof EReference) {
isMany = ((EReference) feature).isMany();
}
return isMany ? new ArrayList() : null;
}
private Object eGet_(EObject obj, EStructuralFeature feature, boolean toModify) {
if (obj == null) {
return null;
}
if (obj instanceof MethodElement) {
PropUtil propUtil = PropUtil.getPropUtil();
MethodElement element = (MethodElement) obj;
if (feature instanceof EReference) {
EReference ref = (EReference) feature;
if (element instanceof Practice) {
PracticePropUtil practicePropUtil = PracticePropUtil.getPracticePropUtil();
Practice practice = (Practice) element;
UserDefinedTypeMeta meta = practicePropUtil.getUdtMeta(practice);
if (meta != null && meta.isQualifiedRefernce((EReference) feature)) {
List list = practicePropUtil.getQReferenceListById(element,
feature.getName(), false);
return list;
}
}
if (ref == UmaUtil.MethodElement_UdtList) {
return propUtil.getUdtList(element, toModify);
}
ExtendedReference eRef = getAssociatedExtendedReference(ref);
if (eRef != null) {
return propUtil.getExtendedReferenceList(element, eRef, toModify);
}
} else if (feature instanceof EAttribute && element instanceof ContentDescription) {
EAttribute att = (EAttribute) feature;
ExtendedAttribute eAtt = getAssociatedExtendedAttribute(att);
if (eAtt != null) {
return propUtil.getExtendedAttribute((ContentDescription) element, eAtt);
}
}
}
return obj.eGet(feature);
}
public void eSet(EObject obj, EStructuralFeature feature, Object newValue) {
try {
eSet_(obj, feature, newValue);
} catch (Throwable e) {
LibraryEditPlugin.getDefault().getLogger().logError(e);
if (DebugUtil.udtDebug || DebugUtil.uiDebug) {
e.printStackTrace();
}
}
}
private void eSet_(EObject obj, EStructuralFeature feature, Object newValue) {
if (obj instanceof ContentDescription) {
ExtendedAttribute eAtt = getAssociatedExtendedAttribute(feature);
if (eAtt != null && (newValue == null || newValue instanceof String) ) {
PropUtil.getPropUtil().setExtendedAttribute((ContentDescription) obj, eAtt, (String) newValue);
return;
}
}
obj.eSet(feature, newValue);
}
public void eBasicSet(EObject obj, EStructuralFeature feature, Object newValue) {
boolean oldB = obj.eDeliver();
try {
if (oldB) {
obj.eSetDeliver(false);
}
eSet(obj, feature, newValue);
} finally {
if (oldB) {
obj.eSetDeliver(true);
}
}
}
public List<EReference> getEAllReferences(MethodElement element) {
List<EReference> list = new ArrayList<EReference>(element.eClass().getEAllReferences());
if (element instanceof Practice) {
PracticePropUtil practicePropUtil = PracticePropUtil.getPracticePropUtil();
Practice practice = (Practice) element;
UserDefinedTypeMeta meta = practicePropUtil.getUdtMeta(practice);
if (meta != null && !meta.getQualifiedReferences().isEmpty()) {
list.addAll(meta.getQualifiedReferences());
}
}
PropUtil propUtil = PropUtil.getPropUtil();
list.add(UmaUtil.MethodElement_UdtList);
ModifiedTypeMeta meta = propUtil.getGlobalMdtMeta(element);
if (meta != null) {
list = new ArrayList<EReference>(list);
for (ExtendedReference eRef : meta.getReferences()) {
list.add(eRef.getReference());
for (QualifiedReference qRef : eRef.getQualifiedReferences()) {
list.add(qRef.getReference());
}
}
}
return list;
}
public List<EAttribute> getEAllAttributes(MethodElement element) {
List<EAttribute> list =new ArrayList<EAttribute>(element.eClass().getEAllAttributes());
if (! (element instanceof ContentDescription)) {
return list;
}
EObject owner = element.eContainer();
if (! (owner instanceof MethodElement)) {
return list;
}
PropUtil propUtil = PropUtil.getPropUtil();
ModifiedTypeMeta meta = propUtil.getGlobalMdtMeta((MethodElement) owner);
if (meta == null) {
return list;
}
for (ExtendedAttribute eAtt : meta.getRtes()) {
list.add(eAtt.getAttribute());
}
return list;
}
public MethodElementExt createExtendObject(MethodElement element) {
PropUtil propUtil = PropUtil.getPropUtil();
if (propUtil.isWorkProductState(element)) {
return new WorkProductStateExt((Constraint) element);
}
if (element instanceof Descriptor) {
return new DescriptorExt((Descriptor) element);
}
if (element instanceof MethodPlugin) {
return new MethodPluginExt((MethodPlugin) element);
}
return new MethodElementExt(element);
}
public static Class getSuperClass(Class cls) {
Class cls1 = ContentElement.class;
Class cls2 = BreakdownElement.class;
Class[] ins = cls.getInterfaces();
if (ins == null || ins.length == 0) {
return null;
}
for (Class in : ins) {
if (cls1.isAssignableFrom(in) || cls2.isAssignableFrom(in)) {
return in;
}
}
return null;
}
public static ModifiedTypeMeta getMdtMeta(EClass cls) {
try {
MethodElement element = (MethodElement) UmaFactory.eINSTANCE
.create(cls);
return getMdtMeta(element);
} catch (Exception e) {
return null;
}
}
public static ModifiedTypeMeta getMdtMeta(MethodElement element) {
return PropUtil.getPropUtil().getGlobalMdtMeta(element);
}
public static ModifiedTypeMeta getLinkedMdtMeta(MethodElement element) {
ModifiedTypeMeta meta = getMdtMeta(element);
if (meta == null) {
return null;
}
Collection<ModifiedTypeMeta> allTypes = LibraryEditUtil.getInstance().getModifiedTypes();
if (allTypes == null) {
return null;
}
for (ModifiedTypeMeta oMeta : allTypes) {
if (! oMeta.getLinkTypes().isEmpty() && meta.getId().equals(oMeta.getLinkTypes().get(0))) {
return oMeta;
}
}
return null;
}
public static boolean hasLinkTypes(MethodElement element) {
ModifiedTypeMeta meta = getMdtMeta(element);
if (meta == null) {
return false;
}
return meta.getLinkTypes() != null && ! meta.getLinkTypes().isEmpty();
}
public static String getTypeId(MethodElement element) {
if (element instanceof Practice) {
UserDefinedTypeMeta meta = PracticePropUtil.getPracticePropUtil().getUdtMeta((Practice) element);
if (meta != null) {
return meta.getRteNameMap().get(UserDefinedTypeMeta._typeId);
}
}
return element.eClass().getInstanceClass().getName();
}
public static boolean isTypeOf(MethodElement element, String typeId) {
String elementTypeId = getTypeId(element);
if (elementTypeId.equals(typeId)) {
return true;
}
for (EClass cls : element.eClass().getEAllSuperTypes()) {
Class c = cls.getInstanceClass();
if (c.getName().equals(typeId)) {
return true;
}
}
return false;
}
public void validateId(String context, String id) throws TypeDefException {
String errorMsg = checkIdValue(context, id);
if (errorMsg != null) {
throw new TypeDefException(errorMsg);
}
}
public String checkIdValue(String context, String id) {
if (id == null || id.trim().length() == 0) {
return "Invalid id string for " + context + ": id cannot be null or empty!";//$NON-NLS-1$ //$NON-NLS-2$
}
char c = id.charAt(0);
if (! (c == '_' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
return "Invalid id string for " + context + ": " + id + "\nid must start with an letter or underscore";//$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
}
char lastC = c;
for (int i = 1 ; i < id.length(); i++) {
c = id.charAt(i);
boolean valid = (c == '_' || c == '-' || c == '.' || c >= '0' && c <= '9' || (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'));
if (c == '.' && lastC == c) {
valid = false;
}
if (! valid) {
return "Invalid id string for " + context + ": " + id + "\nid can only contain letters, digits, underscores, hyphens, and single periods";//$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
}
lastC = c;
}
return null;
}
public ModifiedTypeMeta newModifiedTypeMeta() {
return new ModifiedTypeMetaImpl();
}
private static String indent0 = " "; //$NON-NLS-1$
public static String getMTypesDebugString(Collection<ModifiedTypeMeta> mtypes, String label) {
List<ModifiedTypeMeta> list = new ArrayList<ModifiedTypeMeta>();
if (mtypes != null) {
list.addAll(mtypes);
}
Collections.sort(list);
StringBuffer sb = new StringBuffer();
if (label == null) {
label = "";
}
sb.append(label + "\n"); //$NON-NLS-1$
sb.append("size: " + list.size() + "\n"); //$NON-NLS-1$
if (list.isEmpty()) {
return sb.toString();
}
for (int i = 0; i < list.size(); i++) {
ModifiedTypeMeta meta = list.get(i);
sb.append(meta.getDebugString(i, indent0));
}
return sb.toString();
}
}