blob: 85d65f9ccb37b55e7cb7e76519af30822d1825c2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2006 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 API and implementation
*******************************************************************************/
/*
*/
package org.eclipse.jem.internal.beaninfo.adapters;
import java.io.*;
import java.util.*;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.change.*;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jem.internal.beaninfo.*;
import org.eclipse.jem.internal.beaninfo.common.*;
import org.eclipse.jem.internal.beaninfo.core.BeaninfoPlugin;
import org.eclipse.jem.internal.beaninfo.core.Utilities;
import org.eclipse.jem.internal.beaninfo.impl.*;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.java.*;
/**
* This is a utility class for handling the BeanInfo decorators with respect to the overrides (explicit settings) vs. introspected/reflected (implicit
* settings) It handles the transmission of data from the VM for introspection.
* @since 1.1.0
*/
public class BeanInfoDecoratorUtility {
/**
* Clear out the implicit settings for FeatureDecorator.
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(FeatureDecorator decor) {
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_DISPLAYNAME_IMPLICIT) != 0)
decor.unsetDisplayName();
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_SHORTDESC_IMPLICIT) != 0)
decor.unsetShortDescription();
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_CATEGORY_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getFeatureDecorator_Category());
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_EXPERT_IMPLICIT) != 0)
decor.unsetExpert();
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_HIDDEN_IMPLICIT) != 0)
decor.unsetHidden();
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_PREFERRED_IMPLICIT) != 0)
decor.unsetPreferred();
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_ATTRIBUTES_IMPLICIT) != 0) {
for (Iterator itr = decor.getAttributes().listIterator(); itr.hasNext();) {
FeatureAttributeMapEntryImpl entry = (FeatureAttributeMapEntryImpl)itr.next();
if (entry.getTypedValue().isImplicitValue()) {
itr.remove();
}
}
}
decor
.setImplicitlySetBits(implicitSettings
& ~(FeatureDecoratorImpl.FEATURE_DISPLAYNAME_IMPLICIT | FeatureDecoratorImpl.FEATURE_SHORTDESC_IMPLICIT
| FeatureDecoratorImpl.FEATURE_CATEGORY_IMPLICIT | FeatureDecoratorImpl.FEATURE_EXPERT_IMPLICIT
| FeatureDecoratorImpl.FEATURE_HIDDEN_IMPLICIT | FeatureDecoratorImpl.FEATURE_PREFERRED_IMPLICIT | FeatureDecoratorImpl.FEATURE_ATTRIBUTES_IMPLICIT));
}
/**
* Clear out the implicit settings for BeanDecorator
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(BeanDecorator decor) {
clear((FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & BeanDecoratorImpl.BEAN_CUSTOMIZER_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getBeanDecorator_CustomizerClass());
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_PROPERTIES_IMPLICIT) != 0)
decor.unsetMergeSuperProperties();
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_OPERATIONS_IMPLICIT) != 0)
decor.unsetMergeSuperMethods();
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_EVENTS_IMPLICIT) != 0)
decor.unsetMergeSuperEvents();
if (decor.eIsSet(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedPropertyNames()))
decor.eUnset(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedPropertyNames()); // Just clear them. This is our attribute. It should
// not be set overrides.
if (decor.eIsSet(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedMethodNames()))
decor.eUnset(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedMethodNames()); // Just clear them. This is our attribute. It should
// not be set overrides.
if (decor.eIsSet(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedEventNames()))
decor.eUnset(BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedEventNames()); // Just clear them. This is our attribute. It should not
// be set overrides.
decor.setImplicitlySetBits(implicitSettings
& ~(BeanDecoratorImpl.BEAN_CUSTOMIZER_IMPLICIT | BeanDecoratorImpl.BEAN_MERGE_INHERITED_PROPERTIES_IMPLICIT
| BeanDecoratorImpl.BEAN_MERGE_INHERITED_OPERATIONS_IMPLICIT | BeanDecoratorImpl.BEAN_MERGE_INHERITED_EVENTS_IMPLICIT));
}
/**
* Clear out the implicit settings of the PropertyDecorator.
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(PropertyDecorator decor) {
clear((FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_EDITOR_CLASS_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getPropertyDecorator_PropertyEditorClass());
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_READMETHOD_IMPLICIT) != 0)
decor.unsetReadMethod();
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_WRITEMETHOD_IMPLICIT) != 0)
decor.unsetWriteMethod();
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_FIELD_IMPLICIT) != 0) {
decor.unsetField();
decor.eUnset(BeaninfoPackage.eINSTANCE.getPropertyDecorator_Field());
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT) != 0)
decor.unsetBound();
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_CONSTRAINED_IMPLICIT) != 0)
decor.unsetConstrained();
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_DESIGNTIME_IMPLICIT) != 0)
decor.unsetDesignTime();
decor.setImplicitlySetBits(implicitSettings
& ~(PropertyDecoratorImpl.PROPERTY_EDITOR_CLASS_IMPLICIT | PropertyDecoratorImpl.PROPERTY_READMETHOD_IMPLICIT
| PropertyDecoratorImpl.PROPERTY_WRITEMETHOD_IMPLICIT | PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT
| PropertyDecoratorImpl.PROPERTY_CONSTRAINED_IMPLICIT | PropertyDecoratorImpl.PROPERTY_DESIGNTIME_IMPLICIT));
}
/**
* Clear out the implicit settings of the IndexedPropertyDecorator.
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(IndexedPropertyDecorator decor) {
clear((PropertyDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & IndexedPropertyDecoratorImpl.INDEXED_READMETHOD_IMPLICIT) != 0)
decor.unsetIndexedReadMethod();
if ((implicitSettings & IndexedPropertyDecoratorImpl.INDEXED_WRITEMETHOD_IMPLICIT) != 0)
decor.unsetIndexedWriteMethod();
decor.setImplicitlySetBits(implicitSettings
& ~(IndexedPropertyDecoratorImpl.INDEXED_READMETHOD_IMPLICIT | IndexedPropertyDecoratorImpl.INDEXED_WRITEMETHOD_IMPLICIT));
}
/**
* Clear the method decorator of any implicit settings.
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(MethodDecorator decor) {
clear((FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & (MethodDecoratorImpl.METHOD_PARAMETERS_IMPLICIT | MethodDecoratorImpl.METHOD_PARAMETERS_DEFAULT)) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getMethodDecorator_SerParmDesc());
decor.setImplicitlySetBits(implicitSettings
& ~(MethodDecoratorImpl.METHOD_PARAMETERS_IMPLICIT | MethodDecoratorImpl.METHOD_PARAMETERS_DEFAULT));
}
/**
* Clear the event set decorator of any implicit settings.
*
* @param decor
*
* @since 1.1.0
*/
public static void clear(EventSetDecorator decor) {
clear((FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
// For each setting, see if it was implicitly set, and if it was, then unset it.
if ((implicitSettings & EventSetDecoratorImpl.EVENT_ADDLISTENERMETHOD_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getEventSetDecorator_AddListenerMethod());
if ((implicitSettings & EventSetDecoratorImpl.EVENT_ADAPTERCLASS_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getEventSetDecorator_EventAdapterClass());
if ((implicitSettings & (EventSetDecoratorImpl.EVENT_LISTENERMETHODS_IMPLICIT | EventSetDecoratorImpl.EVENT_LISTENERMETHODS_DEFAULT)) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getEventSetDecorator_SerListMthd());
if ((implicitSettings & EventSetDecoratorImpl.EVENT_REMOVELISTENERMETHOD_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getEventSetDecorator_RemoveListenerMethod());
if ((implicitSettings & EventSetDecoratorImpl.EVENT_DEFAULTEVENTSET_IMPLICIT) != 0)
decor.unsetInDefaultEventSet();
if ((implicitSettings & EventSetDecoratorImpl.EVENT_UNICAST_IMPLICIT) != 0)
decor.unsetUnicast();
if ((implicitSettings & EventSetDecoratorImpl.EVENT_LISTENERTYPE_IMPLICIT) != 0)
decor.eUnset(BeaninfoPackage.eINSTANCE.getEventSetDecorator_ListenerType());
decor.setImplicitlySetBits(implicitSettings
& ~(EventSetDecoratorImpl.EVENT_ADDLISTENERMETHOD_IMPLICIT | EventSetDecoratorImpl.EVENT_ADAPTERCLASS_IMPLICIT
| EventSetDecoratorImpl.EVENT_LISTENERMETHODS_IMPLICIT | EventSetDecoratorImpl.EVENT_LISTENERMETHODS_DEFAULT
| EventSetDecoratorImpl.EVENT_REMOVELISTENERMETHOD_IMPLICIT | EventSetDecoratorImpl.EVENT_DEFAULTEVENTSET_IMPLICIT
| EventSetDecoratorImpl.EVENT_UNICAST_IMPLICIT | EventSetDecoratorImpl.EVENT_LISTENERTYPE_IMPLICIT));
}
public static void introspect(IBeanProxy modelBeaninfoProxy, IntrospectCallBack callback) {
ProxyIntrospectCallBack cb = new ProxyIntrospectCallBack(callback);
modelBeaninfoProxy.getProxyFactoryRegistry().getCallbackRegistry().registerCallback(modelBeaninfoProxy, cb);
try {
BeaninfoProxyConstants.getConstants(modelBeaninfoProxy.getProxyFactoryRegistry()).getSendBeanInfoProxy()
.invokeCatchThrowableExceptions(modelBeaninfoProxy);
} finally {
modelBeaninfoProxy.getProxyFactoryRegistry().getCallbackRegistry().deregisterCallback(modelBeaninfoProxy);
}
}
/**
* This call back is for each requested type of record. It allows the callee to process this record.
*
* @since 1.1.0
*/
public interface IntrospectCallBack {
/**
* Process the BeanDecoratorRecord. The callee can decide what needs to be done with this record. It would return the BeandDecorator that needs
* to have the record applied to. If it returns <code>null</code> then the record will be ignored.
* <p>
* Note: This will be called on a separate thread from that which initiated the request. Therefor be careful with any locks because you may
* have them on a separate thread.
*
* @param record
* @return BeanDecorator to be applied to, or <code>null</code> if record is to be ignored.
*
* @since 1.1.0
*/
public BeanDecorator process(BeanRecord record);
/**
* Process the PropertyRecord. The callee can decide what needs to be done with this record. It would return the PropertyDecorator that needs
* to have the record applied to. If it returns <code>null</code> then the record will be ignored.
* <p>
* Note: This will be called on a separate thread from that which initiated the request. Therefor be careful with any locks because you may
* have them on a separate thread.
*
* @param record
* @return PropertyDecorator to be applied to, or <code>null</code> if record is to be ignored.
*
* @since 1.1.0
*/
public PropertyDecorator process(PropertyRecord record);
/**
* Process the IndexedPropertyRecord. The callee can decide what needs to be done with this record. It would return the
* IndexedPropertyDecorator that needs to have the record applied to. If it returns <code>null</code> then the record will be ignored.
*
* <p>
* Note: This will be called on a separate thread from that which initiated the request. Therefor be careful with any locks because you may
* have them on a separate thread.
*
* @param record
* @return PropertyDecorator to be applied to, or <code>null</code> if record is to be ignored. There is a possibility that a straight
* PropertyDecorator can be returned instead (in the case that it was explictly set by overrides as a property but beaninfo thinks it
* is an index. This can be handled by it will only set the PropertyRecord part. It normally should be an IndexedPropertyDecorator
* returned.
*
* @since 1.1.0
*/
public PropertyDecorator process(IndexedPropertyRecord record);
/**
* Process the MethodRecord. The callee can decide what needs to be done with this record. It would return the MethodDecorator that needs to
* have the record applied to. If it returns <code>null</code> then the record will be ignored.
*
* <p>
* Note: This will be called on a separate thread from that which initiated the request. Therefor be careful with any locks because you may
* have them on a separate thread.
*
* @param record
* @return MethodDecorator to be applied to, or <code>null</code> if record is to be ignored.
*
* @since 1.1.0
*/
public MethodDecorator process(MethodRecord record);
/**
* Process the EventRecord. The callee can decide what needs to be done with this record. It would return the EventSetDecorator that needs to
* have the record applied to. If it returns <code>null</code> then the record will be ignored.
*
* <p>
* Note: This will be called on a separate thread from that which initiated the request. Therefor be careful with any locks because you may
* have them on a separate thread.
*
* @param record
* @return EventSetDecorator to be applied to, or <code>null</code> if record is to be ignored.
*
* @since 1.1.0
*/
public EventSetDecorator process(EventSetRecord record);
}
private static class ProxyIntrospectCallBack implements ICallback {
private IntrospectCallBack introspectCallback;
public ProxyIntrospectCallBack(IntrospectCallBack introspectCallback) {
this.introspectCallback = introspectCallback;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.internal.proxy.core.ICallback#calledBack(int, org.eclipse.jem.internal.proxy.core.IBeanProxy)
*/
public Object calledBack(int msgID, IBeanProxy parm) {
return null; // Not used.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.internal.proxy.core.ICallback#calledBack(int, java.lang.Object)
*/
public Object calledBack(int msgID, Object parm) {
return null; // Not used.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.internal.proxy.core.ICallback#calledBack(int, java.lang.Object[])
*/
public Object calledBack(int msgID, Object[] parms) {
return null; // Not used.
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.internal.proxy.core.ICallback#calledBackStream(int, java.io.InputStream)
*/
public void calledBackStream(int msgID, InputStream is) {
ObjectInputStream ois;
try {
ois = new ObjectInputStream(is);
while (true) {
int cmdId = ois.readInt();
switch (cmdId) {
case IBeanInfoIntrospectionConstants.BEAN_DECORATOR_SENT:
try {
BeanRecord br = (BeanRecord) ois.readObject();
BeanDecorator bd = introspectCallback.process(br);
if (bd != null) {
clear(bd);
applyRecord(bd, br);
}
} catch (IOException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassCastException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassNotFoundException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
}
break;
case IBeanInfoIntrospectionConstants.PROPERTY_DECORATORS_SENT:
try {
int propCount = ois.readInt();
for (int i = 0; i < propCount; i++) {
PropertyRecord pr = (PropertyRecord) ois.readObject();
if (pr.getClass() == IndexedPropertyRecord.class) {
IndexedPropertyRecord ipr = (IndexedPropertyRecord) pr;
PropertyDecorator ip = introspectCallback.process(ipr);
if (ip != null) {
// It actually could be either a property decorator or an indexed property decorator. This could happen
// because the overrides file has explicitly declared a PropertyDecorator, so we can't change it to an
// Indexed.
// So in that case we can only fill the property part.
if (ip.eClass().getClassifierID() == BeaninfoPackage.INDEXED_PROPERTY_DECORATOR)
applyRecord((IndexedPropertyDecorator) ip, ipr);
else
applyRecord(ip, pr); // It was forced to be a property and not indexed.
}
} else {
PropertyDecorator p = introspectCallback.process(pr);
if (p != null) {
// It actually could be either a property decorator or an indexed property decorator. This could happen
// because the overrides file has explicitly declared an IndexedPropertyDecorator, so we can't change it
// to an
// Property.
// So in that case we can only fill the property part.
applyRecord(p, pr);
}
}
}
} catch (IOException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassNotFoundException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassCastException e) {
// In case we got bad data sent in.
BeaninfoPlugin.getPlugin().getLogger().log(e);
} finally {
}
break;
case IBeanInfoIntrospectionConstants.METHOD_DECORATORS_SENT:
try {
int opCount = ois.readInt();
for (int i = 0; i < opCount; i++) {
MethodRecord mr = (MethodRecord) ois.readObject();
MethodDecorator m = introspectCallback.process(mr);
if (m != null)
applyRecord(m, mr);
}
} catch (IOException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassNotFoundException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassCastException e) {
// In case we got bad data sent in.
BeaninfoPlugin.getPlugin().getLogger().log(e);
}
break;
case IBeanInfoIntrospectionConstants.EVENT_DECORATORS_SENT:
try {
int opCount = ois.readInt();
for (int i = 0; i < opCount; i++) {
EventSetRecord evr = (EventSetRecord) ois.readObject();
EventSetDecorator e = introspectCallback.process(evr);
if (e != null)
applyRecord(e, evr);
}
} catch (IOException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassNotFoundException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
} catch (ClassCastException e) {
// In case we got bad data sent in.
BeaninfoPlugin.getPlugin().getLogger().log(e);
}
break;
case IBeanInfoIntrospectionConstants.DONE:
return; // Good. This is a good stop.
default:
return; // This is invalid. Should of gotton something.
}
}
} catch (IOException e) {
BeaninfoPlugin.getPlugin().getLogger().log(e);
}
}
}
/**
* Apply the feature record to the feature decorator. This is protected because this is an abstract and should never be called by itself.
* <p>
*
* @param decor
* @param record
*
* @since 1.1.0
*/
protected static void applyRecord(FeatureDecorator decor, FeatureRecord record) {
// Subclasses will clear their decor, which will automatically clear the FeatureDecor part for us.
long implicitSettings = decor.getImplicitlySetBits();
if (record.displayName != null && !decor.isSetDisplayName()) {
decor.setDisplayName(record.displayName);
implicitSettings |= FeatureDecoratorImpl.FEATURE_DISPLAYNAME_IMPLICIT;
}
if (record.shortDescription != null && !decor.isSetShortDescription()) {
decor.setShortDescription(record.shortDescription);
implicitSettings |= FeatureDecoratorImpl.FEATURE_SHORTDESC_IMPLICIT;
}
if (record.category != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getFeatureDecorator_Category())) {
decor.setCategory(record.category);
implicitSettings |= FeatureDecoratorImpl.FEATURE_CATEGORY_IMPLICIT;
}
if (!decor.isSetExpert()) {
if (decor.isExpert() != record.expert)
decor.setExpert(record.expert); // Don't want to explicitly set it if it is equal to default (this will put less out to the cache file
// and so will parse and apply faster).
implicitSettings |= FeatureDecoratorImpl.FEATURE_EXPERT_IMPLICIT;
}
if (!decor.isSetHidden()) {
if (decor.isHidden() != record.hidden)
decor.setHidden(record.hidden);
implicitSettings |= FeatureDecoratorImpl.FEATURE_HIDDEN_IMPLICIT;
}
if (!decor.isSetPreferred()) {
if (decor.isPreferred() != record.preferred)
decor.setPreferred(record.preferred);
implicitSettings |= FeatureDecoratorImpl.FEATURE_PREFERRED_IMPLICIT;
}
if (record.attributeNames != null && !decor.isAttributesExplicitEmpty()) {
// This is a list, so we need to read an fill in.
EMap attrs = decor.getAttributes();
for (int i = 0; i < record.attributeNames.length; i++) {
FeatureAttributeMapEntryImpl entry = (FeatureAttributeMapEntryImpl) ((BeaninfoFactoryImpl) BeaninfoFactory.eINSTANCE)
.createFeatureAttributeMapEntry();
entry.setTypedKey(record.attributeNames[i]);
FeatureAttributeValue fv = record.attributeValues[i];
fv.setImplicitValue(true);
entry.setTypedValue(fv);
attrs.add(entry);
}
implicitSettings |= FeatureDecoratorImpl.FEATURE_ATTRIBUTES_IMPLICIT;
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Apply the bean record to the bean decorator.
*
* @param decor
* @param record
*
* @since 1.1.0
*/
public static void applyRecord(BeanDecorator decor, BeanRecord record) {
applyRecord((FeatureDecorator) decor, record);
long implicitSettings = decor.getImplicitlySetBits();
if (record.customizerClassName != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getBeanDecorator_CustomizerClass())) {
decor.setCustomizerClass(createJavaClassProxy(record.customizerClassName));
implicitSettings |= BeanDecoratorImpl.BEAN_CUSTOMIZER_IMPLICIT;
}
if (!decor.isSetMergeSuperProperties()) {
if (decor.isMergeSuperProperties() != record.mergeInheritedProperties)
decor.setMergeSuperProperties(record.mergeInheritedProperties);
implicitSettings |= BeanDecoratorImpl.BEAN_MERGE_INHERITED_PROPERTIES_IMPLICIT;
}
if (!decor.isSetMergeSuperMethods()) {
if (decor.isMergeSuperMethods() != record.mergeInheritedOperations)
decor.setMergeSuperMethods(record.mergeInheritedOperations);
implicitSettings |= BeanDecoratorImpl.BEAN_MERGE_INHERITED_OPERATIONS_IMPLICIT;
}
if (!decor.isSetMergeSuperEvents()) {
if (decor.isMergeSuperEvents() != record.mergeInheritedEvents)
decor.setMergeSuperEvents(record.mergeInheritedEvents);
implicitSettings |= BeanDecoratorImpl.BEAN_MERGE_INHERITED_EVENTS_IMPLICIT;
}
if (record.notInheritedPropertyNames != null) {
// This is always applied. This isn't a client override so we can just slam it.
decor.getNotInheritedPropertyNames().addAll(Arrays.asList(record.notInheritedPropertyNames));
}
if (record.notInheritedOperationNames != null) {
// This is always applied. This isn't a client override so we can just slam it.
decor.getNotInheritedMethodNames().addAll(Arrays.asList(record.notInheritedOperationNames));
}
if (record.notInheritedEventNames != null) {
// This is always applied. This isn't a client override so we can just slam it.
decor.getNotInheritedEventNames().addAll(Arrays.asList(record.notInheritedEventNames));
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Apply the PropertyRecord to the PropertyDecorator.
*
* @param decor
* @param record
*
* @since 1.1.0
*/
public static void applyRecord(PropertyDecorator decor, PropertyRecord record) {
applyRecord((FeatureDecorator) decor, record);
applyOnly(decor, record);
}
/*
* Apply only to property decorator part. Allows IndexedProperty to apply just the Property part and not do duplicate work
*/
private static void applyOnly(PropertyDecorator decor, PropertyRecord record) {
long implicitSettings = decor.getImplicitlySetBits();
if (record.propertyEditorClassName != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getPropertyDecorator_PropertyEditorClass())) {
decor.setPropertyEditorClass(createJavaClassProxy(record.propertyEditorClassName));
implicitSettings |= PropertyDecoratorImpl.PROPERTY_EDITOR_CLASS_IMPLICIT;
}
if (record.readMethod != null && !decor.isSetReadMethod()) {
decor.setReadMethod(createJavaMethodProxy(record.readMethod));
implicitSettings |= PropertyDecoratorImpl.PROPERTY_READMETHOD_IMPLICIT;
}
if (record.writeMethod != null && !decor.isSetWriteMethod()) {
decor.setWriteMethod(createJavaMethodProxy(record.writeMethod));
implicitSettings |= PropertyDecoratorImpl.PROPERTY_WRITEMETHOD_IMPLICIT;
}
if (record.field != null && !decor.isSetField()) {
decor.setField(createJavaFieldProxy(record.field));
if (decor.isFieldReadOnly() != record.field.readOnly)
decor.setFieldReadOnly(record.field.readOnly);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_FIELD_IMPLICIT;
}
if (!decor.isSetBound()) {
if (decor.isBound() != record.bound)
decor.setBound(record.bound);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT;
}
if (!decor.isSetConstrained()) {
if (decor.isConstrained() != record.constrained)
decor.setConstrained(record.constrained);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_CONSTRAINED_IMPLICIT;
}
if (record.designTime != null && !decor.isSetDesignTime()) {
// Design time is slightly different than the other booleans because
// explicitly set to true/false is important versus not explicitly set at all (which is false).
decor.setDesignTime(record.designTime.booleanValue());
implicitSettings |= PropertyDecoratorImpl.PROPERTY_DESIGNTIME_IMPLICIT;
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
public static void applyRecord(IndexedPropertyDecorator decor, IndexedPropertyRecord record) {
applyRecord((FeatureDecorator) decor, record);
applyOnly(decor, record);
long implicitSettings = decor.getImplicitlySetBits();
if (record.indexedReadMethod != null && !decor.isSetIndexedReadMethod()) {
decor.setIndexedReadMethod(createJavaMethodProxy(record.indexedReadMethod));
implicitSettings |= IndexedPropertyDecoratorImpl.INDEXED_READMETHOD_IMPLICIT;
}
if (record.indexedWriteMethod != null && !decor.isSetIndexedWriteMethod()) {
decor.setIndexedWriteMethod(createJavaMethodProxy(record.indexedWriteMethod));
implicitSettings |= IndexedPropertyDecoratorImpl.INDEXED_WRITEMETHOD_IMPLICIT;
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Apply the method record to the method decorator.
*
* @param decor
* @param record
*
* @since 1.1.0
*/
public static void applyRecord(MethodDecorator decor, MethodRecord record) {
applyRecord((FeatureDecorator) decor, record);
long implicitSettings = decor.getImplicitlySetBits();
if (record.parameters != null && !decor.isParmsExplicitEmpty()
&& !decor.eIsSet(BeaninfoPackage.eINSTANCE.getMethodDecorator_ParameterDescriptors())) {
// This is a list, so we need to read an fill in.
List parms = decor.getSerParmDesc(); // So as not to have it implicitly fill it in, which it would if we called getParameterDescriptors.
for (int i = 0; i < record.parameters.length; i++) {
ParameterDecorator parm = BeaninfoFactory.eINSTANCE.createParameterDecorator();
applyRecord(parm, record.parameters[i]);
parms.add(parm);
}
implicitSettings |= MethodDecoratorImpl.METHOD_PARAMETERS_IMPLICIT;
implicitSettings &= ~MethodDecoratorImpl.METHOD_PARAMETERS_DEFAULT; // Should of already been cleared, but be safe.
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
public static void applyRecord(ParameterDecorator decor, ParameterRecord record) {
applyRecord((FeatureDecorator) decor, record);
long implicitSettings = decor.getImplicitlySetBits();
if (record.name != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getParameterDecorator_Name())) {
decor.setName(record.name);
implicitSettings |= ParameterDecoratorImpl.PARAMETER_NAME_IMPLICIT;
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Apply the event set record to the event set decorator.
*
* @param decor
* @param record
*
* @since 1.1.0
*/
public static void applyRecord(EventSetDecorator decor, EventSetRecord record) {
applyRecord((FeatureDecorator) decor, record);
long implicitSettings = decor.getImplicitlySetBits();
if (record.addListenerMethod != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_AddListenerMethod())) {
decor.setAddListenerMethod(createJavaMethodProxy(record.addListenerMethod));
implicitSettings |= EventSetDecoratorImpl.EVENT_ADDLISTENERMETHOD_IMPLICIT;
}
if (record.eventAdapterClassName != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_EventAdapterClass())) {
decor.setEventAdapterClass(createJavaClassProxy(record.eventAdapterClassName));
implicitSettings |= EventSetDecoratorImpl.EVENT_ADAPTERCLASS_IMPLICIT;
}
if (record.listenerMethodDescriptors != null && !decor.isListenerMethodsExplicitEmpty()
&& !decor.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_ListenerMethods())) {
List methods = decor.getSerListMthd(); // So as not to have it implicitly fill it in, which it would if we called getListenerMethods.
for (int i = 0; i < record.listenerMethodDescriptors.length; i++) {
BeaninfoFactory bfact = BeaninfoFactory.eINSTANCE;
MethodRecord mr = record.listenerMethodDescriptors[i];
Method method = createJavaMethodProxy(mr.methodForDescriptor);
// We need a method proxy, and a method decorator.
MethodProxy mproxy = bfact.createMethodProxy();
mproxy.setMethod(method);
mproxy.setName(mr.name);
MethodDecorator md = bfact.createMethodDecorator();
applyRecord(md, mr);
mproxy.getEAnnotations().add(md);
methods.add(mproxy);
}
implicitSettings |= EventSetDecoratorImpl.EVENT_LISTENERMETHODS_IMPLICIT;
implicitSettings &= ~EventSetDecoratorImpl.EVENT_LISTENERMETHODS_DEFAULT; // Should of already been cleared, but be safe.
}
if (record.listenerTypeName != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_ListenerType())) {
decor.setListenerType(createJavaClassProxy(record.listenerTypeName));
implicitSettings |= EventSetDecoratorImpl.EVENT_LISTENERTYPE_IMPLICIT;
}
if (record.removeListenerMethod != null && !decor.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_RemoveListenerMethod())) {
decor.setRemoveListenerMethod(createJavaMethodProxy(record.removeListenerMethod));
implicitSettings |= EventSetDecoratorImpl.EVENT_REMOVELISTENERMETHOD_IMPLICIT;
}
if (!decor.isSetInDefaultEventSet()) {
if (record.inDefaultEventSet != decor.isInDefaultEventSet())
decor.setInDefaultEventSet(record.inDefaultEventSet);
implicitSettings |= EventSetDecoratorImpl.EVENT_DEFAULTEVENTSET_IMPLICIT;
}
if (!decor.isSetUnicast()) {
if (record.unicast != decor.isUnicast())
decor.setUnicast(record.unicast);
implicitSettings |= EventSetDecoratorImpl.EVENT_UNICAST_IMPLICIT;
}
decor.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Create a java class proxy for the given name. By being a proxy we don't need to actually have the resource set. Nor do we need to fluff one up
* until someone actually asks for it.
* <p>
* The jniName must refer to a JavaClass or errors could occur later on.
*
* @param jniName
* classname in JNI format.
* @return JavaClass proxy or <code>null</code> if not a java class (it may be a type).
*
* @since 1.1.0
*/
public static JavaClass createJavaClassProxy(String jniName) {
JavaHelpers jh = createJavaTypeProxy(jniName);
return jh instanceof JavaClass ? (JavaClass) jh : null;
}
/**
* Create a JavaHelpers proxy for the given name. By being a proxy we don't need to actually have the resource set. Nor do we need to fluff one up
* until someone actually asks for it.
*
* @param jniName
* typename in JNI format.
* @return JavaHelper proxy.
*
* @since 1.1.0
*/
public static JavaHelpers createJavaTypeProxy(String jniName) {
String formalName = MapJNITypes.getFormalTypeName(jniName);
URI uri = Utilities.getJavaClassURI(formalName);
JavaHelpers jh = null;
if (MapJNITypes.isFormalTypePrimitive(formalName))
jh = JavaRefFactory.eINSTANCE.createJavaDataType();
else
jh = JavaRefFactory.eINSTANCE.createJavaClass();
((InternalEObject) jh).eSetProxyURI(uri);
return jh;
}
public static Method createJavaMethodProxy(ReflectMethodRecord method) {
String[] parmTypes = method.parameterTypeNames != null ? new String[method.parameterTypeNames.length] : null;
if (parmTypes != null)
for (int i = 0; i < method.parameterTypeNames.length; i++) {
parmTypes[i] = MapJNITypes.getFormalTypeName(method.parameterTypeNames[i]);
}
URI uri = Utilities.getMethodURI(MapJNITypes.getFormalTypeName(method.className), method.methodName, parmTypes);
Method methodEMF = JavaRefFactory.eINSTANCE.createMethod();
((InternalEObject) methodEMF).eSetProxyURI(uri);
return methodEMF;
}
public static Field createJavaFieldProxy(ReflectFieldRecord field) {
URI uri = Utilities.getFieldURI(MapJNITypes.getFormalTypeName(field.className), field.fieldName);
Field fieldEMF = JavaRefFactory.eINSTANCE.createField();
((InternalEObject) fieldEMF).eSetProxyURI(uri);
return fieldEMF;
}
/**
* Set the properties on the PropertyDecorator. These come from reflection. Since this is a private interface between BeaninfoClassAdapter and
* this class, not all possible settings need to be mentioned. Only the ones that can be set by reflection. It is assumed that clear has already
* been done so that there are no old implicit settings. It will check if properties are set already before setting so that don't wipe out
* explicit settings.
*
* @param prop
* @param bound
* @param constrained
* @param getter
* @param setter
*
* @since 1.1.0
*/
public static void setProperties(PropertyDecorator prop, boolean bound, boolean constrained, Method getter, Method setter) {
long implicitSettings = prop.getImplicitlySetBits();
if (getter != null && !prop.isSetReadMethod()) {
prop.setReadMethod(getter);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_READMETHOD_IMPLICIT;
}
if (setter != null && !prop.isSetWriteMethod()) {
prop.setWriteMethod(setter);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_WRITEMETHOD_IMPLICIT;
}
if (!prop.isSetBound()) {
if (prop.isBound() != bound)
prop.setBound(bound);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT;
}
if (!prop.isSetConstrained()) {
if (prop.isConstrained() != constrained)
prop.setConstrained(constrained);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_CONSTRAINED_IMPLICIT;
}
prop.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Set the properties on the IndexedPropertyDecorator. These come from reflection. It is only the indexed portion. The base property portion
* should have already been set. Since this is a private interface between BeaninfoClassAdapter and this class, not all possible settings need to
* be mentioned. Only the ones that can be set by reflection. It is assumed that clear has already been done so that there are no old implicit
* settings. It will check if properties are set already before setting so that don't wipe out explicit settings.
*
* @param prop
* @param indexedGetter
* @param indexedSetter
*
* @since 1.1.0
*/
public static void setProperties(IndexedPropertyDecorator prop, Method indexedGetter, Method indexedSetter) {
long implicitSettings = prop.getImplicitlySetBits();
if (indexedGetter != null && !prop.isSetIndexedReadMethod()) {
prop.setIndexedReadMethod(indexedGetter);
implicitSettings |= IndexedPropertyDecoratorImpl.INDEXED_READMETHOD_IMPLICIT;
}
if (indexedSetter != null && !prop.isSetIndexedWriteMethod()) {
prop.setIndexedWriteMethod(indexedSetter);
implicitSettings |= IndexedPropertyDecoratorImpl.INDEXED_WRITEMETHOD_IMPLICIT;
}
prop.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Set the properties on the EventSetDecorator. These come from reflection. Since this is a private interface between BeaninfoClassAdapter and
* this class, not all possible settings need to be mentioned. Only the ones that can be set by reflection. It is assumed that clear has already
* been done so that there are no old implicit settings. It will check if properties are set already before setting so that don't wipe out
* explicit settings.
*
* @param event
* @param bound
* @param constrained
* @param getter
* @param setter
*
* @since 1.1.0
*/
public static void setProperties(EventSetDecorator event, Method addListenerMethod, Method removeListenerMethod, boolean unicast,
JavaClass listenerType) {
long implicitSettings = event.getImplicitlySetBits();
if (addListenerMethod != null && !event.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_AddListenerMethod())) {
event.setAddListenerMethod(addListenerMethod);
implicitSettings |= EventSetDecoratorImpl.EVENT_ADDLISTENERMETHOD_IMPLICIT;
}
if (removeListenerMethod != null && !event.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_RemoveListenerMethod())) {
event.setRemoveListenerMethod(removeListenerMethod);
implicitSettings |= EventSetDecoratorImpl.EVENT_REMOVELISTENERMETHOD_IMPLICIT;
}
if (!event.isSetUnicast()) {
if (event.isUnicast() != unicast)
event.setUnicast(unicast);
implicitSettings |= PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT;
}
if (listenerType != null && !event.eIsSet(BeaninfoPackage.eINSTANCE.getEventSetDecorator_ListenerType())) {
event.setListenerType(listenerType);
implicitSettings |= EventSetDecoratorImpl.EVENT_LISTENERTYPE_IMPLICIT;
}
event.setImplicitlySetBits(implicitSettings); // Now save was implicitly set.
}
/**
* Build the appropriate change record for the bean decorator. Either it is an add of a new bean decorator or it is the setting of the implicit
* settings on an non-implicit bean decorator.
* @param cd
* @param bd
*
* @since 1.1.0
*/
public static void buildChange(ChangeDescription cd, BeanDecorator bd) {
// Only do anything if merge introspection. If no merge introspection, then there is no change needed.
if (bd.isMergeIntrospection()) {
if (bd.getImplicitDecoratorFlag() != ImplicitItem.NOT_IMPLICIT_LITERAL) {
// It is implicit, so do an add to end, new value.
doAddToEnd(cd, getFeatureChangeList(cd, bd.getEModelElement()), EcorePackage.eINSTANCE.getEModelElement_EAnnotations(), bd, true);
} else {
// Just do sets on implicit changed ones
buildNonImplicitChange(cd, getFeatureChangeList(cd, bd), bd);
}
}
}
/**
* Build the appropriate change record for the property decorator. Either it is an add of a new property decorator or it is the setting of the implicit
* settings on an non-implicit property decorator. The same is true of the feature that it decorates. It may be new or it may be an existing one.
* @param cd
* @param pd
*
* @since 1.1.0
*/
public static void buildChange(ChangeDescription cd, PropertyDecorator pd) {
// Only do changes if merge introspection. If not merging, then there are no changes.
if (pd.isMergeIntrospection()) {
boolean indexed = pd.eClass().getClassifierID() == BeaninfoPackage.INDEXED_PROPERTY_DECORATOR;
EStructuralFeature feature = (EStructuralFeature) pd.getEModelElement();
switch (pd.getImplicitDecoratorFlag().getValue()) {
case ImplicitItem.IMPLICIT_DECORATOR:
// The decorator is implicit, so clone it, and apply to feature, and then do the standard property applies to the feature.
List fcs = getFeatureChangeList(cd, feature);
doAddToEnd(cd, fcs, pd.eContainingFeature(), pd, true);
buildNonImplicitChange(cd, fcs, feature, indexed);
break;
case ImplicitItem.IMPLICIT_DECORATOR_AND_FEATURE:
// The decorator AND feature are implicit. Just clone them and add to the class.
doAddToEnd(cd, getFeatureChangeList(cd, feature.eContainer()), feature.eContainingFeature(), feature, true);
break;
case ImplicitItem.NOT_IMPLICIT:
// Neither the feature nor the decorator are implicit. So need to do applies against them.
buildNonImplicitChange(cd, getFeatureChangeList(cd, pd), pd, indexed);
buildNonImplicitChange(cd, getFeatureChangeList(cd, feature), feature, indexed);
break;
}
}
}
/**
* Build the appropriate change record for the event set decorator. Either it is an add of a new event set decorator or it is the setting of the implicit
* settings on an non-implicit event set decorator. The same is true of the feature that it decorates. It may be new or it may be an existing one.
* @param cd
* @param ed
*
* @since 1.1.0
*/
public static void buildChange(ChangeDescription cd, EventSetDecorator ed) {
// Only build changes if merge introspection. If not merge then there are no changes.
if (ed.isMergeIntrospection()) {
JavaEvent event = (JavaEvent) ed.getEModelElement();
switch (ed.getImplicitDecoratorFlag().getValue()) {
case ImplicitItem.IMPLICIT_DECORATOR:
// The decorator is implicit, so clone it, and apply to feature, and then do the standard property applies to the feature.
List fcs = getFeatureChangeList(cd, event);
doAddToEnd(cd, fcs, ed.eContainingFeature(), ed, true);
buildNonImplicitChange(cd, fcs, event);
break;
case ImplicitItem.IMPLICIT_DECORATOR_AND_FEATURE:
// The decorator AND feature are implicit. Just clone them and add to the class.
doAddToEnd(cd, getFeatureChangeList(cd, event.eContainer()), event.eContainingFeature(), event, true);
break;
case ImplicitItem.NOT_IMPLICIT:
// Neither the feature nor the decorator are implicit. So need to do applies against them.
buildNonImplicitChange(cd, getFeatureChangeList(cd, ed), ed);
buildNonImplicitChange(cd, getFeatureChangeList(cd, event), event);
break;
}
}
}
/**
* Build the appropriate change record for the method decorator. Either it is an add of a new method decorator or it is the setting of the implicit
* settings on an non-implicit method decorator. The same is true of the operation that it decorates. It may be new or it may be an existing one.
* @param cd
* @param md
*
* @since 1.1.0
*/
public static void buildChange(ChangeDescription cd, MethodDecorator md) {
// Only do any builds if merge introspection. If not merge introspection then nothing should be changed.
if (md.isMergeIntrospection()) {
EOperation oper = (EOperation) md.getEModelElement();
switch (md.getImplicitDecoratorFlag().getValue()) {
case ImplicitItem.IMPLICIT_DECORATOR:
// The decorator is implicit, so clone it, and apply to feature, and then do the standard property applies to the feature.
List fcs = getFeatureChangeList(cd, oper);
doAddToEnd(cd, fcs, md.eContainingFeature(), md, true);
buildNonImplicitChange(cd, fcs, oper);
break;
case ImplicitItem.IMPLICIT_DECORATOR_AND_FEATURE:
// The decorator AND feature are implicit. Just clone them and add to the class.
doAddToEnd(cd, getFeatureChangeList(cd, oper.eContainer()), oper.eContainingFeature(), oper, true);
break;
case ImplicitItem.NOT_IMPLICIT:
// Neither the feature nor the decorator are implicit. So need to do applies against them.
buildNonImplicitChange(cd, getFeatureChangeList(cd, md), md);
buildNonImplicitChange(cd, getFeatureChangeList(cd, oper), oper);
break;
}
}
}
private final static Integer ZERO = new Integer(0);
private final static Integer ONE = new Integer(1);
private final static Integer MINUS_ONE = new Integer(-1);
/**
* Build the non-implicit changes into the feature. This creates changes for the implicit settings
* that always occur for a property decorator.
*
* @param cd
* @param fcs FeatureChanges list for the feature.
* @param feature
* @param indexed <code>true</code> if this is for an indexed feature.
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, EStructuralFeature feature, boolean indexed) {
doSet(cd, fcs, EcorePackage.eINSTANCE.getENamedElement_Name(), feature.getName(), false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getEStructuralFeature_Transient(), Boolean.FALSE, false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getEStructuralFeature_Volatile(), Boolean.FALSE, false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getEStructuralFeature_Changeable(), Boolean.valueOf(feature.isChangeable()), false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_EType(), feature.getEType(), false);
if (!indexed) {
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_LowerBound(), ZERO, false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_UpperBound(), ONE, false);
} else {
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_LowerBound(), ZERO, false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_UpperBound(), MINUS_ONE, false);
doSet(cd, fcs, EcorePackage.eINSTANCE.getETypedElement_Unique(), Boolean.TRUE, false);
}
}
/**
* Build the non-implicit changes into the event. This creates changes for the implicit settings
* that always occur for an event set decorator.
*
* @param cd
* @param fcs FeatureChanges list for the feature.
* @param event
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, JavaEvent event) {
doSet(cd, fcs, EcorePackage.eINSTANCE.getENamedElement_Name(), event.getName(), false);
}
/**
* Build the non-implicit changes into the operation. This creates changes for the implicit settings
* that always occur for an method decorator.
*
* @param cd
* @param fcs FeatureChanges list for the feature.
* @param oper
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, EOperation oper) {
doSet(cd, fcs, EcorePackage.eINSTANCE.getENamedElement_Name(), oper.getName(), false);
try {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getMethodProxy_Method(), ((MethodProxy) oper).getMethod(), false); // This is a method that is not in this resource, so no clone.
} catch (ClassCastException e) {
// It will be a MethodProxy 99.9% of the time, so save by not doing instanceof.
}
}
/**
* Build up the changes for a non-implicit feature decorator. This means create changes for implicit set features.
*
* @param cd
* @param fcs
* the FeatureChanges list for the given decorator.
* @param decor
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, FeatureDecorator decor) {
long implicitSettings = decor.getImplicitlySetBits();
if (implicitSettings != 0)
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_ImplicitlySetBits(), new Long(implicitSettings), false);
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_DISPLAYNAME_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_DisplayName(), decor.getDisplayName(), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_SHORTDESC_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_ShortDescription(), decor.getShortDescription(), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_CATEGORY_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_Category(), decor.getCategory(), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_EXPERT_IMPLICIT) != 0 && decor.isSetExpert()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_Expert(), Boolean.valueOf(decor.isExpert()), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_HIDDEN_IMPLICIT) != 0 && decor.isSetHidden()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_Hidden(), Boolean.valueOf(decor.isHidden()), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_PREFERRED_IMPLICIT) != 0 && decor.isSetPreferred()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_Preferred(), Boolean.valueOf(decor.isPreferred()), false);
}
if ((implicitSettings & FeatureDecoratorImpl.FEATURE_ATTRIBUTES_IMPLICIT) != 0) {
for (Iterator itr = decor.getAttributes().listIterator(); itr.hasNext();) {
FeatureAttributeMapEntryImpl entry = (FeatureAttributeMapEntryImpl)itr.next();
if (entry.getTypedValue().isImplicitValue()) {
doAddToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getFeatureDecorator_Attributes(), entry, true);
}
}
}
}
/**
* Build up the changes for a non-implicit bean decorator. This means create changes for implicit set features.
*
* @param cd
* @param fcs
* the FeatureChanges list for the given decorator.
* @param decor
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, BeanDecorator decor) {
buildNonImplicitChange(cd, fcs, (FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
if ((implicitSettings & BeanDecoratorImpl.BEAN_CUSTOMIZER_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_CustomizerClass(), decor.getCustomizerClass(), false); // Customizer class is
// not in this resource,
// so we don't clone it.
}
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_PROPERTIES_IMPLICIT) != 0 && decor.isSetMergeSuperProperties()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_MergeSuperProperties(), Boolean.valueOf(decor.isMergeSuperProperties()), false);
}
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_OPERATIONS_IMPLICIT) != 0 && decor.isSetMergeSuperMethods()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_MergeSuperMethods(), Boolean.valueOf(decor.isMergeSuperMethods()), false);
}
if ((implicitSettings & BeanDecoratorImpl.BEAN_MERGE_INHERITED_EVENTS_IMPLICIT) != 0 && decor.isSetMergeSuperEvents()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_MergeSuperEvents(), Boolean.valueOf(decor.isMergeSuperEvents()), false);
}
if (!decor.getNotInheritedPropertyNames().isEmpty()) {
doAddAllToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedPropertyNames(), decor.getNotInheritedPropertyNames(), false);
}
if (!decor.getNotInheritedMethodNames().isEmpty()) {
doAddAllToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedMethodNames(), decor.getNotInheritedMethodNames(), false);
}
if (!decor.getNotInheritedEventNames().isEmpty()) {
doAddAllToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getBeanDecorator_NotInheritedEventNames(), decor.getNotInheritedEventNames(), false);
}
}
/**
* Build up the changes for a non-implicit property decorator. This means create changes for implicit set features.
*
* @param cd
* @param fcs
* the FeatureChanges list for the given decorator.
* @param decor
* @param indexed <code>true</code> if this is an indexed property decorator.
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, PropertyDecorator decor, boolean indexed) {
buildNonImplicitChange(cd, fcs, decor);
long implicitSettings = decor.getImplicitlySetBits();
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_EDITOR_CLASS_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_PropertyEditorClass(), decor.getPropertyEditorClass(), false); // Property Editor class is
// not in this resource,
// so we don't clone it.
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_READMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_ReadMethod(), decor.getReadMethod(), false);
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_WRITEMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_WriteMethod(), decor.getWriteMethod(), false);
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_FIELD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_Field(), decor.getField(), false);
if (decor.eIsSet(BeaninfoPackage.eINSTANCE.getPropertyDecorator_FieldReadOnly()))
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_FieldReadOnly(), Boolean.valueOf(decor.isFieldReadOnly()), false);
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_BOUND_IMPLICIT) != 0 && decor.isSetBound()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_Bound(), Boolean.valueOf(decor.isBound()), false);
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_CONSTRAINED_IMPLICIT) != 0 && decor.isSetConstrained()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_Constrained(), Boolean.valueOf(decor.isConstrained()), false);
}
if ((implicitSettings & PropertyDecoratorImpl.PROPERTY_DESIGNTIME_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getPropertyDecorator_DesignTime(), Boolean.valueOf(decor.isDesignTime()), false);
}
if (indexed) {
IndexedPropertyDecorator ipd = (IndexedPropertyDecorator) decor;
if ((implicitSettings & IndexedPropertyDecoratorImpl.INDEXED_READMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getIndexedPropertyDecorator_IndexedReadMethod(), ipd.getIndexedReadMethod(), false);
}
if ((implicitSettings & IndexedPropertyDecoratorImpl.INDEXED_WRITEMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getIndexedPropertyDecorator_IndexedWriteMethod(), ipd.getIndexedWriteMethod(), false);
}
}
}
/**
* Build up the changes for a non-implicit event set decorator. This means create changes for implicit set features.
*
* @param cd
* @param fcs
* the FeatureChanges list for the given decorator.
* @param decor
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, EventSetDecorator decor) {
buildNonImplicitChange(cd, fcs, (FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
if ((implicitSettings & EventSetDecoratorImpl.EVENT_ADDLISTENERMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_AddListenerMethod(), decor.getAddListenerMethod(), false); // listener method is
// not in this resource,
// so we don't clone it.
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_ADAPTERCLASS_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_EventAdapterClass(), decor.getEventAdapterClass(), false);
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_LISTENERMETHODS_IMPLICIT) != 0) {
doAddAllToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_SerListMthd(), decor.getSerListMthd(), true); // These need to be cloned because they are contained here.
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_LISTENERTYPE_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_ListenerType(), decor.getListenerType(), false);
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_REMOVELISTENERMETHOD_IMPLICIT) != 0) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_RemoveListenerMethod(), decor.getRemoveListenerMethod(), false);
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_DEFAULTEVENTSET_IMPLICIT) != 0 && decor.isSetInDefaultEventSet()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_InDefaultEventSet(), Boolean.valueOf(decor.isInDefaultEventSet()), false);
}
if ((implicitSettings & EventSetDecoratorImpl.EVENT_UNICAST_IMPLICIT) != 0 && decor.isSetUnicast()) {
doSet(cd, fcs, BeaninfoPackage.eINSTANCE.getEventSetDecorator_Unicast(), Boolean.valueOf(decor.isUnicast()), false);
}
}
/**
* Build up the changes for a non-implicit method decorator. This means create changes for implicit set features.
*
* @param cd
* @param fcs
* the FeatureChanges list for the given decorator.
* @param decor
*
* @since 1.1.0
*/
protected static void buildNonImplicitChange(ChangeDescription cd, List fcs, MethodDecorator decor) {
buildNonImplicitChange(cd, fcs, (FeatureDecorator) decor);
long implicitSettings = decor.getImplicitlySetBits();
if ((implicitSettings & MethodDecoratorImpl.METHOD_PARAMETERS_IMPLICIT) != 0) {
doAddAllToEnd(cd, fcs, BeaninfoPackage.eINSTANCE.getMethodDecorator_SerParmDesc(), decor.getSerParmDesc(), true);
}
}
/**
* Get the feature change list for an object. Create it one if necessary.
*
* @param cd
* @param object
* @return feature change list.
*
* @since 1.1.0
*/
protected static List getFeatureChangeList(ChangeDescription cd, EObject object) {
List fcs = cd.getObjectChanges().get(object); // Get the feature changes if any.
if (fcs == null) {
Map.Entry entry = ChangeFactory.eINSTANCE.createEObjectToChangesMapEntry(object);
cd.getObjectChanges().add(entry);
fcs = (List) entry.getValue();
}
return fcs;
}
/**
* Return the FeatureChange record for a feature wrt/object. Create one if necessary. If it creates it, it will mark it as "set". All of our
* changes here are set kind of changes, not unset kind.
*
* @param fcs
* feature change list from the ChangeDescripion.getObjectChanges for the given object.
* @param feature
* @return feature change
*
* @since 1.1.0
*/
protected static FeatureChange getFeatureChange(List fcs, EStructuralFeature feature) {
if (!fcs.isEmpty()) {
for (int i = 0; i < fcs.size(); i++) {
FeatureChange fc = (FeatureChange) fcs.get(i);
if (fc.getFeature() == feature)
return fc;
}
}
// Either new object changes or no feature change found. Create one.
FeatureChange fc = ChangeFactory.eINSTANCE.createFeatureChange(feature, null, true);
fcs.add(fc);
return fc;
}
/**
* Create a change for add to end of the given feature (must be isMany()). If newObject is true, then this means this is not a pointer to an
* existing object and so it must be cloned. It is assumed that there will be no further changes to this object because those will not be known
* about.
*
* @param cd
* @param fcs
* feature change list from the ChangeDescripion.getObjectChanges for the given object.
* @param feature
* the feature being added to.
* @param addedValue
* the value being added.
* @param newValue
* <code>true</code> if new object in the resource, a clone will be made. <code>false</code> if an existing object. Must be an
* EObject for cloning. Best if not true for non-eobjects.
* @return the addedValue or the clone if it was cloned.
*
* @since 1.1.0
*/
protected static Object doAddToEnd(ChangeDescription cd, List fcs, EStructuralFeature feature, Object addedValue, boolean newValue) {
FeatureChange fc = getFeatureChange(fcs, feature);
if (newValue) {
try {
addedValue = EcoreUtil.copy((EObject) addedValue);
cd.getObjectsToAttach().add((EObject)addedValue);
} catch (ClassCastException e) {
// Normally should not occur, but if it does, it means we can't clone, so don't clone.
}
}
List lcs = fc.getListChanges();
// Find the one with add and -1, i.e. add to end. There should only be one.
ListChange lc = null;
for (int i = 0; i < lcs.size(); i++) {
ListChange lca = (ListChange) lcs.get(i);
if (lca.getKind() == ChangeKind.ADD_LITERAL && lca.getIndex() == -1) {
lc = lca;
break;
}
}
if (lc == null) {
lc = ChangeFactory.eINSTANCE.createListChange();
lcs.add(lc);
}
lc.getValues().add(addedValue);
return addedValue;
}
/**
* Create a change for add all to end of the given feature (must be isMany()). If newValue is true, then this means this is not a pointer to
* existing objects and so it must be cloned. It is assumed that there will be no further changes to this object because those will not be known
* about.
*
* @param cd
* @param fcs
* feature change list from the ChangeDescripion.getObjectChanges for the given object.
* @param feature
* the feature being added to.
* @param addedValues
* the values being added.
* @param newValue
* <code>true</code> if new objects in the resource, clones will be made. <code>false</code> if an existing object. Must be EObject
* for cloning. Best if not true for non-eobjects.
* @return the addedValues or the clones if it was cloned.
*
* @since 1.1.0
*/
protected static Object doAddAllToEnd(ChangeDescription cd, List fcs, EStructuralFeature feature, Collection addedValues, boolean newValue) {
FeatureChange fc = getFeatureChange(fcs, feature);
if (newValue) {
try {
addedValues = EcoreUtil.copyAll(addedValues);
cd.getObjectsToAttach().addAll(addedValues);
} catch (ClassCastException e) {
// Normally should not occur, but if it does, it means we can't clone, so don't clone.
}
}
List lcs = fc.getListChanges();
// Find the one with add and -1, i.e. add to end. There should only be one.
ListChange lc = null;
for (int i = 0; i < lcs.size(); i++) {
ListChange lca = (ListChange) lcs.get(i);
if (lca.getKind() == ChangeKind.ADD_LITERAL && lca.getIndex() == -1) {
lc = lca;
break;
}
}
if (lc == null) {
lc = ChangeFactory.eINSTANCE.createListChange();
lcs.add(lc);
}
lc.getValues().addAll(addedValues);
return addedValues;
}
/**
* Create a change for set a given feature (must be !isMany()). If newValue is true, then this means this is not a pointer to an existing object
* and so it must be cloned. It is assumed that there will be no further changes to this object because those will not be known about.
* <p>
* Any further sets to this feature will result in the previous setting being lost.
*
* @param cd
* @param fcs
* feature change list from the ChangeDescripion.getObjectChanges for the given object.
* @param feature
* the feature being set to.
* @param setValue
* the value being set.
* @param newValue
* <code>true</code> if new object in the resource, a clone will be made. <code>false</code> if an existing object. Must be an
* EObject for cloning. Best if not true for non-eobjects.
* @return the setValue or the clone if it was cloned.
*
* @since 1.1.0
*/
protected static Object doSet(ChangeDescription cd, List fcs, EStructuralFeature feature, Object setValue, boolean newValue) {
FeatureChange fc = getFeatureChange(fcs, feature);
if (newValue) {
try {
setValue = EcoreUtil.copy((EObject) setValue);
cd.getObjectsToAttach().add((EObject)setValue);
} catch (ClassCastException e) {
// Normally should not occur, but if it does, it means we can't clone, so don't clone.
}
}
if (setValue instanceof EObject)
fc.setReferenceValue((EObject) setValue);
else
fc.setDataValue(EcoreUtil.convertToString((EDataType) feature.getEType(), setValue));
return setValue;
}
}