/******************************************************************************* * 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; } }