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