use of org.glassfish.hk2.xml.jaxb.internal.BaseHK2JAXBBean in project glassfish-hk2 by eclipse-ee4j.
the class Utilities method internalAdd.
@SuppressWarnings("unchecked")
public static BaseHK2JAXBBean internalAdd(BaseHK2JAXBBean myParent, String childPropertyNamespace, String childProperty, Object rawChild, String childKey, int index, DynamicChangeInfo<?> changeInformation, XmlDynamicChange xmlDynamicChange, List<ActiveDescriptor<?>> addedServices, boolean changeList) {
if (index < -1) {
throw new IllegalArgumentException("Unknown index " + index);
}
if (childKey != null && myParent._lookupChild(childPropertyNamespace, childProperty, childKey) != null) {
throw new IllegalStateException("There is already a child with name " + childKey + " for child " + childProperty);
}
if (rawChild != null && !(rawChild instanceof BaseHK2JAXBBean)) {
throw new IllegalArgumentException("The child added must be from XmlService.createBean");
}
ParentedModel childNode = myParent._getModel().getChild(childPropertyNamespace, childProperty);
if (childNode == null) {
throw new IllegalArgumentException("There is no child with xmlTag " + childProperty + " of " + myParent);
}
Object allMyChildren = myParent._getProperty(childPropertyNamespace, childProperty);
List<Object> multiChildren = null;
if (!ChildType.DIRECT.equals(childNode.getChildType())) {
if (allMyChildren == null) {
multiChildren = new ArrayList<Object>(10);
} else {
if (ChildType.LIST.equals(childNode.getChildType())) {
multiChildren = new ArrayList<Object>((List<Object>) allMyChildren);
} else {
multiChildren = new ArrayList<Object>(Arrays.asList((Object[]) allMyChildren));
}
}
if (changeList && index > multiChildren.size()) {
throw new IllegalArgumentException("The index given to add child " + childProperty + " to " + myParent + " is not in range (" + index + "," + multiChildren.size() + ")");
}
if (index == -1) {
index = multiChildren.size();
}
}
BaseHK2JAXBBean child = createBean(childNode.getChildModel().getProxyAsClass());
child._setClassReflectionHelper(myParent._getClassReflectionHelper());
if (rawChild != null) {
// Handling of children will be handled once the real child is better setup
BaseHK2JAXBBean childToCopy = (BaseHK2JAXBBean) rawChild;
for (QName nonChildProperty : childToCopy._getModel().getNonChildProperties().keySet()) {
String nonChildPropNamespace = QNameUtilities.getNamespace(nonChildProperty);
String nonChildPropKey = nonChildProperty.getLocalPart();
Object value = childToCopy._getProperty(nonChildPropNamespace, nonChildPropKey);
if (value == null)
continue;
child._setProperty(nonChildPropNamespace, nonChildPropKey, value, false, true);
}
}
if (childKey == null) {
if (childNode.getChildModel().getKeyProperty() != null) {
if (rawChild != null) {
String keyPropNamespace = QNameUtilities.getNamespace(childNode.getChildModel().getKeyProperty());
String keyPropKey = childNode.getChildModel().getKeyProperty().getLocalPart();
childKey = (String) child._getProperty(keyPropNamespace, keyPropKey);
}
if (childKey == null) {
throw new IllegalArgumentException("Attempted to create child with xmlTag " + childProperty + " with no key field in " + myParent);
}
child._setKeyValue(childKey);
} else if (!ChildType.DIRECT.equals(childNode.getChildType())) {
// This is a multi-child with no key and no key property, must generate a key
if (myParent._getChangeControl() == null) {
childKey = NOT_UNIQUE_UNIQUE_ID;
child._setKeyValue(NOT_UNIQUE_UNIQUE_ID);
} else {
childKey = myParent._getChangeControl().getGeneratedId();
child._setKeyValue(childKey);
}
}
} else {
/* childKey != null */
if (childNode.getChildModel().getKeyProperty() == null) {
throw new IllegalArgumentException("Attempted to add an unkeyed child with key " + childKey + " in " + myParent);
}
QName keyProp = childNode.getChildModel().getKeyProperty();
child._setProperty(QNameUtilities.getNamespace(keyProp), keyProp.getLocalPart(), childKey, false, true);
child._setKeyValue(childKey);
}
child._setParent(myParent);
child._setSelfXmlTag(childNode.getChildXmlNamespace(), constructXmlTag(childNode.getXmlWrapperTag(), childNode.getChildXmlTag()));
child._setKeyValue(childKey);
if (childKey != null) {
child._setInstanceName(composeInstanceName(myParent._getInstanceName(), child._getKeyValue(), childNode.getXmlWrapperTag()));
} else {
child._setInstanceName(composeInstanceName(myParent._getInstanceName(), childNode.getChildXmlTag(), childNode.getXmlWrapperTag()));
}
// Now freeze it
child._setDynamicChangeInfo((XmlRootHandleImpl<?>) myParent._getRoot(), changeInformation);
externalAdd(child, xmlDynamicChange.getDynamicConfiguration(), xmlDynamicChange.getBeanDatabase(), addedServices);
Utilities.invokeVetoableChangeListeners(changeInformation, child, null, child, EMPTY_STRING, myParent._getClassReflectionHelper());
if (rawChild != null) {
// Now we handle the children
handleChildren(child, (BaseHK2JAXBBean) rawChild, changeInformation, addedServices, xmlDynamicChange);
}
if (!changeList) {
return child;
}
// Now modify the actual list
if (multiChildren != null) {
// List or Array child
multiChildren.add(index, child);
Object finalChildList;
if (ChildType.LIST.equals(childNode.getChildType())) {
finalChildList = Collections.unmodifiableList(multiChildren);
} else {
// ARRAY
finalChildList = Array.newInstance(childNode.getChildModel().getOriginalInterfaceAsClass(), multiChildren.size());
for (int lcv = 0; lcv < multiChildren.size(); lcv++) {
Array.set(finalChildList, lcv, multiChildren.get(lcv));
}
}
if (xmlDynamicChange.getBeanDatabase() != null) {
myParent._changeInHub(childPropertyNamespace, childProperty, finalChildList, xmlDynamicChange.getBeanDatabase());
}
myParent._setProperty(childPropertyNamespace, childProperty, finalChildList, false, true);
} else {
// Direct child
if (xmlDynamicChange.getBeanDatabase() != null) {
myParent._changeInHub(childPropertyNamespace, childProperty, child, xmlDynamicChange.getBeanDatabase());
}
myParent._setProperty(childPropertyNamespace, childProperty, child, false, true);
}
return child;
}
use of org.glassfish.hk2.xml.jaxb.internal.BaseHK2JAXBBean in project glassfish-hk2 by eclipse-ee4j.
the class Utilities method getDescriptorsToRemove.
@SuppressWarnings("unchecked")
private static void getDescriptorsToRemove(BaseHK2JAXBBean fromMe, HashSet<ActiveDescriptor<?>> descriptorsToRemove) {
ActiveDescriptor<?> fromMeDescriptor = fromMe._getSelfDescriptor();
if (fromMeDescriptor == null)
return;
descriptorsToRemove.add(fromMeDescriptor);
ModelImpl model = fromMe._getModel();
if (model == null)
return;
for (ParentedModel parentedChild : model.getAllChildren()) {
String childPropertyNamespace = parentedChild.getChildXmlNamespace();
String childPropertyName = parentedChild.getChildXmlTag();
switch(parentedChild.getChildType()) {
case LIST:
List<BaseHK2JAXBBean> listChildren = (List<BaseHK2JAXBBean>) fromMe._getProperty(childPropertyNamespace, childPropertyName);
if (listChildren != null) {
for (BaseHK2JAXBBean listChild : listChildren) {
getDescriptorsToRemove(listChild, descriptorsToRemove);
}
}
break;
case ARRAY:
Object arrayChildren = fromMe._getProperty(childPropertyNamespace, childPropertyName);
if (arrayChildren != null) {
int arrayLength = Array.getLength(arrayChildren);
for (int lcv = 0; lcv < arrayLength; lcv++) {
BaseHK2JAXBBean bean = (BaseHK2JAXBBean) Array.get(arrayChildren, lcv);
getDescriptorsToRemove(bean, descriptorsToRemove);
}
}
break;
case DIRECT:
BaseHK2JAXBBean bean = (BaseHK2JAXBBean) fromMe._getProperty(childPropertyNamespace, childPropertyName);
if (bean != null) {
getDescriptorsToRemove(bean, descriptorsToRemove);
}
break;
default:
throw new AssertionError("Unknown child type " + parentedChild.getChildType());
}
}
}
use of org.glassfish.hk2.xml.jaxb.internal.BaseHK2JAXBBean in project glassfish-hk2 by eclipse-ee4j.
the class Utilities method getListDifferences.
@SuppressWarnings("unchecked")
private static void getListDifferences(ParentedModel pModel, Object sourceValue, Object otherValue, Differences differences, String xmlTag, BaseHK2JAXBBean source) {
Difference localDifference = new Difference(source);
QName keyProperty = pModel.getChildModel().getKeyProperty();
List<BaseHK2JAXBBean> sourceValueList = (List<BaseHK2JAXBBean>) sourceValue;
List<BaseHK2JAXBBean> otherValueList = (List<BaseHK2JAXBBean>) otherValue;
if (sourceValueList == null)
sourceValueList = Collections.emptyList();
if (otherValueList == null)
otherValueList = Collections.emptyList();
if (keyProperty != null) {
String keyPropertyNamespace = QNameUtilities.getNamespace(keyProperty);
String keyPropertyKey = keyProperty.getLocalPart();
Map<String, Integer> sourceIndexMap = getIndexMap(sourceValueList, keyPropertyNamespace, keyPropertyKey);
Map<String, Integer> otherIndexMap = getIndexMap(otherValueList, keyPropertyNamespace, keyPropertyKey);
for (BaseHK2JAXBBean sourceBean : sourceValueList) {
String sourceKeyValue = sourceBean._getKeyValue();
if (!otherIndexMap.containsKey(sourceKeyValue)) {
localDifference.addRemove(xmlTag, new RemoveData(xmlTag, sourceKeyValue, sourceBean));
} else {
int sourceIndex = sourceIndexMap.get(sourceKeyValue);
int otherIndex = otherIndexMap.get(sourceKeyValue);
Object otherBean = otherValueList.get(otherIndex);
if (otherIndex != sourceIndex) {
localDifference.addMove(xmlTag, new MoveData(sourceIndex, otherIndex));
}
// Need to know sub-differences
getAllDifferences(sourceBean, (BaseHK2JAXBBean) otherBean, differences);
}
}
for (BaseHK2JAXBBean otherBean : otherValueList) {
String otherKeyValue = otherBean._getKeyValue();
if (otherKeyValue == null) {
otherKeyValue = (String) otherBean._getProperty(keyPropertyNamespace, keyPropertyKey);
}
if (!sourceIndexMap.containsKey(otherKeyValue)) {
int addedIndex = otherIndexMap.get(otherKeyValue);
localDifference.addAdd(xmlTag, otherBean, addedIndex);
}
}
} else {
// Both lists are there, this is an unkeyed list, we go *purely* on list size
UnkeyedDiff unkeyedDiff = new UnkeyedDiff(sourceValueList, otherValueList, source, pModel);
Differences unkeyedDiffs = unkeyedDiff.compute();
differences.merge(unkeyedDiffs);
}
if (localDifference.isDirty()) {
differences.addDifference(localDifference);
}
}
use of org.glassfish.hk2.xml.jaxb.internal.BaseHK2JAXBBean in project glassfish-hk2 by eclipse-ee4j.
the class Utilities method getIndexMapArray.
private static Map<String, Integer> getIndexMapArray(Object array, String keyPropertyNamespace, String keyProperty) {
Map<String, Integer> retVal = new HashMap<String, Integer>();
int length = Array.getLength(array);
for (int lcv = 0; lcv < length; lcv++) {
BaseHK2JAXBBean bean = (BaseHK2JAXBBean) Array.get(array, lcv);
String key = bean._getKeyValue();
if (key == null) {
key = (String) bean._getProperty(keyPropertyNamespace, keyProperty);
if (key == null) {
throw new AssertionError("Found a keyed bean with no key " + bean + " at index " + lcv);
}
}
retVal.put(key, lcv);
}
return retVal;
}
use of org.glassfish.hk2.xml.jaxb.internal.BaseHK2JAXBBean in project glassfish-hk2 by eclipse-ee4j.
the class XmlRootHandleImpl method overlay.
/* (non-Javadoc)
* @see org.glassfish.hk2.xml.api.XmlRootHandle#overlay(org.glassfish.hk2.xml.api.XmlRootHandle)
*/
@Override
public void overlay(XmlRootHandle<T> newRoot) {
if (!(newRoot instanceof XmlRootHandle)) {
throw new IllegalArgumentException("newRoot must have been created by the same XmlService as this one");
}
XmlRootHandleImpl<T> newRootImpl = (XmlRootHandleImpl<T>) newRoot;
if (newRootImpl.isAdvertisedInHub()) {
throw new IllegalArgumentException("The newRoot must not be advertised in the Hub");
}
if (newRootImpl.isAdvertisedInLocator()) {
throw new IllegalArgumentException("The newRoot must not be advertised as hk2 services");
}
if (root == null) {
throw new IllegalArgumentException("This XmlRootHandle must have a root to be overlayed");
}
T newRootRoot = newRootImpl.getRoot();
if (newRootRoot == null) {
throw new IllegalArgumentException("The newRoot must have a root to overlay onto this root");
}
if (!(newRootRoot instanceof BaseHK2JAXBBean)) {
throw new IllegalArgumentException("The newRoot has a root of an unknown type: " + newRootRoot.getClass().getName());
}
if (!newRootRoot.getClass().equals(root.getClass())) {
throw new IllegalArgumentException("The two roots must have the same class as this root, instead it is of type " + newRootRoot.getClass().getName());
}
if (newRootRoot.equals(root)) {
throw new IllegalArgumentException("Cannot overlay the same bean on top of itself");
}
BaseHK2JAXBBean newRootBase = (BaseHK2JAXBBean) newRootRoot;
BaseHK2JAXBBean oldRootBase = (BaseHK2JAXBBean) root;
boolean success = false;
XmlHandleTransaction<T> handle = lockForTransaction();
try {
Differences differences = Utilities.getDiff(oldRootBase, newRootBase);
if (!differences.getDifferences().isEmpty()) {
Utilities.applyDiff(differences, changeControl);
}
success = true;
} finally {
if (success) {
handle.commit();
} else {
handle.abandon();
}
}
}
Aggregations