| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| package org.apache.openaz.xacml.admin.model; |
| |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import javax.xml.bind.JAXBElement; |
| |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.ExpressionType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.FunctionType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType; |
| import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import org.apache.openaz.xacml.admin.jpa.FunctionArgument; |
| import org.apache.openaz.xacml.admin.jpa.FunctionDefinition; |
| import org.apache.openaz.xacml.admin.util.JPAUtils; |
| import org.apache.openaz.xacml.admin.util.XACMLFunctionValidator; |
| import com.vaadin.data.Container; |
| import com.vaadin.data.Item; |
| import com.vaadin.data.Property; |
| import com.vaadin.data.util.MethodProperty; |
| |
| public class ExpressionContainer extends ItemSetChangeNotifier implements Container.Hierarchical, Container.ItemSetChangeNotifier { |
| private static final long serialVersionUID = 1L; |
| private static Log logger = LogFactory.getLog(ExpressionContainer.class); |
| |
| /** |
| * String identifier of a file's "name" property. |
| */ |
| public static String PROPERTY_NAME = "Name"; |
| |
| /** |
| * String identifier of an object's "id" property. |
| */ |
| public static String PROPERTY_ID = "Id"; |
| |
| /** |
| * String identifier of an object's "datatype" property. |
| */ |
| public static String PROPERTY_DATATYPE_SHORT = "shortDatatype"; |
| |
| /** |
| * String identifier of an object's "id" property. |
| */ |
| public static String PROPERTY_ID_SHORT = "shortId"; |
| |
| /** |
| * String identifier of an object's "datatype" property. |
| */ |
| public static String PROPERTY_DATATYPE = "Datatype"; |
| |
| /** |
| * List of the string identifiers for the available properties. |
| */ |
| public static Collection<String> EXPRESSION_PROPERTIES; |
| |
| private final static Method EXPRESSIONITEM_NAME; |
| |
| private final static Method EXPRESSIONITEM_ID; |
| |
| private final static Method EXPRESSIONITEM_DATATYPE; |
| |
| private final static Method EXPRESSIONITEM_ID_SHORT; |
| |
| private final static Method EXPRESSIONITEM_DATATYPE_SHORT; |
| |
| static { |
| EXPRESSION_PROPERTIES = new ArrayList<String>(); |
| EXPRESSION_PROPERTIES.add(PROPERTY_NAME); |
| EXPRESSION_PROPERTIES.add(PROPERTY_ID); |
| EXPRESSION_PROPERTIES.add(PROPERTY_DATATYPE); |
| EXPRESSION_PROPERTIES.add(PROPERTY_ID_SHORT); |
| EXPRESSION_PROPERTIES.add(PROPERTY_DATATYPE_SHORT); |
| EXPRESSION_PROPERTIES = Collections.unmodifiableCollection(EXPRESSION_PROPERTIES); |
| try { |
| EXPRESSIONITEM_NAME = ExpressionItem.class.getMethod("getName", new Class[]{}); |
| EXPRESSIONITEM_ID = ExpressionItem.class.getMethod("getId", new Class[]{}); |
| EXPRESSIONITEM_DATATYPE = ExpressionItem.class.getMethod("getDatatype", new Class[]{}); |
| EXPRESSIONITEM_ID_SHORT = ExpressionItem.class.getMethod("getIdShort", new Class[]{}); |
| EXPRESSIONITEM_DATATYPE_SHORT = ExpressionItem.class.getMethod("getDatatypeShort", new Class[]{}); |
| } catch (final NoSuchMethodException e) { |
| throw new RuntimeException( |
| "Internal error finding methods in PolicyContainer"); |
| } |
| } |
| |
| protected class ApplyParent { |
| ApplyType apply; |
| FunctionArgument argument; |
| |
| public ApplyParent(ApplyType apply, FunctionArgument argument) { |
| this.apply = apply; |
| this.argument = argument; |
| } |
| |
| public ApplyType getApply() { |
| return apply; |
| } |
| |
| public void setApply(ApplyType apply) { |
| this.apply = apply; |
| } |
| |
| public FunctionArgument getArgument() { |
| return argument; |
| } |
| |
| public void setArgument(FunctionArgument argument) { |
| this.argument = argument; |
| } |
| } |
| // |
| // Our parent object information and which argument we are |
| // from our parent (relevant to the Apply). |
| // |
| private final Object parent; |
| private final FunctionArgument argument; |
| // |
| // The root object of the expression |
| // |
| private Object root; |
| // |
| // Our helper tables for organization purposes and to |
| // make sure the correct functions/datatypes are being |
| // setup. |
| // |
| private Map<ApplyType, ApplyParent> applys = new HashMap<ApplyType, ApplyParent>(); |
| private Map<FunctionType, ApplyParent> functions = new HashMap<FunctionType, ApplyParent>(); |
| private Map<AttributeValueType, ApplyParent> values = new HashMap<AttributeValueType, ApplyParent>(); |
| private Map<AttributeDesignatorType, ApplyParent> designators = new HashMap<AttributeDesignatorType, ApplyParent>(); |
| private Map<AttributeSelectorType, ApplyParent> selectors = new HashMap<AttributeSelectorType, ApplyParent>(); |
| private Map<VariableReferenceType, ApplyParent> variables = new HashMap<VariableReferenceType, ApplyParent>(); |
| private Map<ExpressionType, ApplyParent> expressions = new HashMap<ExpressionType, ApplyParent>(); |
| |
| public ExpressionContainer(Object parent, Object root, FunctionArgument argument) { |
| super(); |
| this.setContainer(this); |
| this.parent = parent; |
| this.root = root; |
| this.argument = argument; |
| this.initialize(); |
| } |
| |
| private void initialize() { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Initializing: " + this.parent + " " + this.argument + " " + this.root); |
| } |
| // |
| // Make sure we support the parent object |
| // |
| @SuppressWarnings("unused") |
| JAXBElement<?> rootElement = null; |
| if (this.parent instanceof ConditionType) { |
| rootElement = ((ConditionType) this.parent).getExpression(); |
| } else if (this.parent instanceof VariableDefinitionType) { |
| rootElement = ((VariableDefinitionType) this.parent).getExpression(); |
| } else if (this.parent instanceof AttributeAssignmentExpressionType) { |
| rootElement = ((AttributeAssignmentExpressionType) this.parent).getExpression(); |
| } else if (this.parent instanceof ApplyType) { |
| // |
| // They must tell us which argument we are |
| // |
| if (this.argument == null) { |
| throw new IllegalArgumentException("Must supply Argument object when editing a parent ApplyType's child node"); |
| } |
| // |
| // Finish the initialization |
| // |
| this.initializeRoot(); |
| } else { |
| throw new IllegalArgumentException("Unsupported Parent Object: " + this.parent.getClass().getCanonicalName()); |
| } |
| /* |
| // |
| // Check if there actually is a root |
| // |
| if (rootElement == null || rootElement.getValue() == null) { |
| // |
| // Creating a new one |
| // |
| return; |
| } |
| // |
| // Save the root |
| // |
| this.root = rootElement.getValue(); |
| */ |
| // |
| // Finish initializing |
| // |
| this.initializeRoot(); |
| } |
| |
| private void initializeRoot() { |
| // |
| // Sanity check |
| // |
| if (this.root == null) { |
| return; |
| } |
| // |
| // Figure out the expression type |
| // |
| if (this.root instanceof ApplyType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Apply"); |
| } |
| // |
| // Save it |
| // |
| this.applys.put((ApplyType) this.root, null); |
| // |
| // Determine the function for this Apply |
| // |
| Map<String, FunctionDefinition> functions = JPAUtils.getFunctionIDMap(); |
| FunctionDefinition function = functions.get(((ApplyType) this.root).getFunctionId()); |
| if (function == null) { |
| logger.warn("root apply does not have a function defined"); |
| return; |
| } |
| // |
| // Bring in its children |
| // |
| this.initializeChildren((ApplyType) this.root, function); |
| } else if (this.root instanceof AttributeValueType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Attribute Value"); |
| } |
| // |
| // Save it |
| // |
| this.values.put((AttributeValueType) this.root, null); |
| } else if (this.root instanceof AttributeDesignatorType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Attribute Designator"); |
| } |
| // |
| // Save it |
| // |
| this.designators.put((AttributeDesignatorType) this.root, null); |
| } else if (this.root instanceof AttributeSelectorType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Attribute Selector"); |
| } |
| // |
| // Save it |
| // |
| this.selectors.put((AttributeSelectorType) this.root, null); |
| } else if (this.root instanceof VariableReferenceType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Variable Reference"); |
| } |
| // |
| // Save it |
| // |
| this.variables.put((VariableReferenceType) this.root, null); |
| } else if (this.root instanceof FunctionType) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("Root Is Function"); |
| } |
| // |
| // Save it - Really? I don't think the root would ever be a function. |
| // |
| this.functions.put((FunctionType) this.root, null); |
| } else { |
| throw new IllegalArgumentException("Unsupported Expression Root Item: " + this.root.getClass().getCanonicalName()); |
| } |
| } |
| |
| private void initializeChildren(ApplyType apply, FunctionDefinition function) { |
| int index = 1; |
| for (JAXBElement<?> child : apply.getExpression()) { |
| // |
| // Validate the child |
| // |
| if (child.getValue() == null) { |
| logger.warn("child element " + index + "has a null object."); |
| index++; |
| continue; |
| } |
| if (logger.isTraceEnabled()) { |
| logger.trace("Child " + index + " is " + child.getValue()); |
| } |
| // |
| // Get the argument for this child |
| // |
| if (function == null) { |
| throw new IllegalArgumentException("Apply has children but no function defined."); |
| } |
| FunctionArgument argument = XACMLFunctionValidator.getFunctionArgument(index, function); |
| if (logger.isTraceEnabled()) { |
| logger.trace("Child's argument is: " + argument); |
| } |
| if (argument == null) { |
| //throw new Exception("Unable to find function argument: " + index + " " + function.getId() + " " + function.getShortname()); |
| return; |
| } |
| // |
| // See if its another apply type |
| // |
| if (child.getValue() instanceof ApplyType) { |
| // |
| // Save it |
| // |
| this.applys.put((ApplyType) child.getValue(), new ApplyParent(apply, argument)); |
| // |
| // Get its function information |
| // |
| Map<String, FunctionDefinition> functions = JPAUtils.getFunctionIDMap(); |
| FunctionDefinition childFunction = functions.get(((ApplyType) child.getValue()).getFunctionId()); |
| if (childFunction == null) { |
| logger.warn("Apply object " + index + " does not have a function defined"); |
| } else { |
| // |
| // Bring in its children |
| // |
| this.initializeChildren((ApplyType) child.getValue(), childFunction); |
| } |
| } else if (child.getValue() instanceof AttributeValueType) { |
| // |
| // Save it |
| // |
| this.values.put((AttributeValueType) child.getValue(), new ApplyParent(apply, argument)); |
| } else if (child.getValue() instanceof AttributeDesignatorType) { |
| // |
| // Save it |
| // |
| this.designators.put((AttributeDesignatorType) child.getValue(), new ApplyParent(apply, argument)); |
| } else if (child.getValue() instanceof AttributeSelectorType) { |
| // |
| // Save it |
| // |
| this.selectors.put((AttributeSelectorType) child.getValue(), new ApplyParent(apply, argument)); |
| } else if (child.getValue() instanceof VariableReferenceType) { |
| // |
| // Save it |
| // |
| this.variables.put((VariableReferenceType) child.getValue(), new ApplyParent(apply, argument)); |
| } else if (child.getValue() instanceof FunctionType) { |
| // |
| // Save it |
| // |
| this.functions.put((FunctionType) child.getValue(), new ApplyParent(apply, argument)); |
| } else if (child.getValue() instanceof ExpressionType) { |
| // |
| // Save it |
| // |
| this.expressions.put((ExpressionType) child.getValue(), new ApplyParent(apply, argument)); |
| } else { |
| logger.error("Unknown child type: " + child.getClass().getCanonicalName()); |
| } |
| index++; |
| } |
| } |
| |
| protected boolean isObjectSupported(Object itemId) { |
| if (itemId instanceof ApplyType || |
| itemId instanceof AttributeValueType || |
| itemId instanceof AttributeDesignatorType || |
| itemId instanceof AttributeSelectorType || |
| itemId instanceof VariableReferenceType || |
| itemId instanceof FunctionType || |
| itemId instanceof ExpressionType) { |
| return true; |
| } |
| return false; |
| } |
| |
| protected boolean isParentObjectSupport(Object parent) { |
| if (parent instanceof ApplyType || |
| parent instanceof ConditionType || |
| parent instanceof VariableDefinitionType || |
| parent instanceof AttributeAssignmentExpressionType) { |
| return true; |
| } |
| return false; |
| } |
| |
| public void updateItem(Object itemId) { |
| // |
| // Sanity check |
| // |
| if (this.isObjectSupported(itemId) == false) { |
| return;// null; |
| } |
| // |
| // Notify - the real reason for this function |
| // |
| this.fireItemSetChange(); |
| // |
| // Return the item |
| // |
| //return new ExpressionItem(itemId); |
| } |
| |
| @Override |
| public Item getItem(Object itemId) { |
| if (this.isObjectSupported(itemId) == false) { |
| return null; |
| } |
| return new ExpressionItem(itemId); |
| } |
| |
| @Override |
| public Collection<?> getContainerPropertyIds() { |
| return EXPRESSION_PROPERTIES; |
| } |
| |
| @Override |
| public Collection<?> getItemIds() { |
| final Collection<Object> items = new ArrayList<Object>(); |
| if (this.root != null) { |
| // |
| // Add the root object |
| // |
| items.add(this.root); |
| // |
| // If its an apply, it could have children |
| // |
| if (this.root instanceof ApplyType) { |
| items.add(this.getChildrenIds((ApplyType) this.root, true)); |
| } |
| } |
| if (logger.isTraceEnabled()) { |
| logger.trace("getItemIds (" + items.size() + "):" + items); |
| } |
| return Collections.unmodifiableCollection(items); |
| } |
| |
| protected Collection<?> getChildrenIds(ApplyType apply, boolean recursive) { |
| Collection<Object> items = new ArrayList<Object>(); |
| for (JAXBElement<?> child : apply.getExpression()) { |
| // |
| // Make sure there's a value |
| // |
| if (child.getValue() == null) { |
| continue; |
| } |
| // |
| // What kind is it? |
| // |
| if (child.getValue() instanceof ApplyType) { |
| items.add(child.getValue()); |
| // |
| // Do we add its children? |
| // |
| if (recursive) { |
| items.addAll(this.getChildrenIds((ApplyType) child.getValue(), true)); |
| } |
| } else if (child.getValue() instanceof AttributeValueType) { |
| items.add(child.getValue()); |
| } else if (child.getValue() instanceof AttributeDesignatorType) { |
| items.add(child.getValue()); |
| } else if (child.getValue() instanceof AttributeSelectorType) { |
| items.add(child.getValue()); |
| } else if (child.getValue() instanceof VariableReferenceType) { |
| items.add(child.getValue()); |
| } else if (child.getValue() instanceof FunctionType) { |
| items.add(child.getValue()); |
| } else if (child.getValue() instanceof ExpressionType) { |
| items.add(child.getValue()); |
| } |
| } |
| if (logger.isTraceEnabled()) { |
| logger.trace("getChildrenIds " + apply.getFunctionId() + " (" + items.size() + "):" + items); |
| } |
| return items; |
| } |
| |
| @Override |
| public Property<?> getContainerProperty(Object itemId, Object propertyId) { |
| if (this.isObjectSupported(itemId) == false) { |
| return null; |
| } |
| if (propertyId.equals(PROPERTY_NAME)) { |
| return new MethodProperty<Object>(getType(propertyId), |
| new ExpressionItem(itemId), EXPRESSIONITEM_NAME, null); |
| } |
| |
| if (propertyId.equals(PROPERTY_ID)) { |
| return new MethodProperty<Object>(getType(propertyId), |
| new ExpressionItem(itemId), EXPRESSIONITEM_ID, null); |
| } |
| |
| if (propertyId.equals(PROPERTY_DATATYPE)) { |
| return new MethodProperty<Object>(getType(propertyId), |
| new ExpressionItem(itemId), EXPRESSIONITEM_DATATYPE, null); |
| } |
| |
| if (propertyId.equals(PROPERTY_ID_SHORT)) { |
| return new MethodProperty<Object>(getType(propertyId), |
| new ExpressionItem(itemId), EXPRESSIONITEM_ID_SHORT, null); |
| } |
| |
| if (propertyId.equals(PROPERTY_DATATYPE_SHORT)) { |
| return new MethodProperty<Object>(getType(propertyId), |
| new ExpressionItem(itemId), EXPRESSIONITEM_DATATYPE_SHORT, null); |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public Class<?> getType(Object propertyId) { |
| if (propertyId.equals(PROPERTY_NAME)) { |
| return String.class; |
| } |
| if (propertyId.equals(PROPERTY_ID)) { |
| return String.class; |
| } |
| if (propertyId.equals(PROPERTY_DATATYPE)) { |
| return String.class; |
| } |
| if (propertyId.equals(PROPERTY_ID_SHORT)) { |
| return String.class; |
| } |
| if (propertyId.equals(PROPERTY_DATATYPE_SHORT)) { |
| return String.class; |
| } |
| return null; |
| } |
| |
| @Override |
| public int size() { |
| int size = 0; |
| size += this.applys.size(); |
| size += this.designators.size(); |
| size += this.functions.size(); |
| size += this.selectors.size(); |
| size += this.values.size(); |
| size += this.variables.size(); |
| size += this.expressions.size(); |
| return size; |
| } |
| |
| @Override |
| public boolean containsId(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("containsId: " + itemId); |
| } |
| if (itemId instanceof ApplyType) { |
| return this.applys.containsKey(itemId); |
| } |
| if (itemId instanceof AttributeValueType) { |
| return this.values.containsKey(itemId); |
| } |
| if (itemId instanceof AttributeDesignatorType) { |
| return this.designators.containsKey(itemId); |
| } |
| if (itemId instanceof AttributeSelectorType) { |
| return this.selectors.containsKey(itemId); |
| } |
| if (itemId instanceof VariableReferenceType) { |
| return this.variables.containsKey(itemId); |
| } |
| if (itemId instanceof FunctionType) { |
| return this.functions.containsKey(itemId); |
| } |
| if (itemId instanceof ExpressionType) { |
| return this.expressions.containsKey(itemId); |
| } |
| return false; |
| } |
| |
| @Override |
| public Item addItem(Object itemId) throws UnsupportedOperationException { |
| throw new UnsupportedOperationException("Please use the addItem(Object, Object) method instead."); |
| } |
| |
| @Override |
| public Object addItem() throws UnsupportedOperationException { |
| throw new UnsupportedOperationException("use addItem(Object itemId)"); |
| } |
| |
| public Item addItem(Object itemId, ApplyType parent, FunctionArgument argument) throws UnsupportedOperationException { |
| if (logger.isTraceEnabled()) { |
| logger.trace("addItem: " + itemId + " " + parent + " " + argument); |
| } |
| // |
| // Make sure we support the object |
| // |
| if (this.isObjectSupported(itemId) == false) { |
| return null; |
| } |
| // |
| // Is is a root? |
| // |
| if (parent == null) { |
| // |
| // Setting root |
| // |
| if (this.root != null) { |
| throw new UnsupportedOperationException("Cannot add another root item. Remove the current root first."); |
| } |
| // |
| // Save the root information |
| // |
| this.root = itemId; |
| // |
| // Add its children |
| // |
| this.initializeRoot(); |
| // |
| // Add it to our root container |
| // |
| if (this.parent instanceof ApplyType) { |
| ((ApplyType) this.parent).getExpression().add(this.createElement(this.root)); |
| } else if (this.parent instanceof ConditionType) { |
| ((ConditionType) this.parent).setExpression(this.createElement(this.root)); |
| } else if (this.parent instanceof VariableDefinitionType) { |
| ((VariableDefinitionType) this.parent).setExpression(this.createElement(this.root)); |
| } else if (this.parent instanceof AttributeAssignmentExpressionType) { |
| ((AttributeAssignmentExpressionType) this.parent).setExpression(this.createElement(this.root)); |
| } else { |
| logger.error("unknown parent class: " + this.parent.getClass().getCanonicalName()); |
| } |
| // |
| // Notify that we changed |
| // |
| this.fireItemSetChange(); |
| // |
| // Return new item |
| // |
| return new ExpressionItem(this.root); |
| } |
| // |
| // Check what kind of item this is |
| // |
| if (itemId instanceof ApplyType) { |
| // |
| this.applys.put((ApplyType) itemId, new ApplyParent(parent, argument)); |
| ((ApplyType) parent).getExpression().add(new ObjectFactory().createApply((ApplyType) itemId)); |
| // |
| // Get its function information |
| // |
| Map<String, FunctionDefinition> functions = JPAUtils.getFunctionIDMap(); |
| FunctionDefinition childFunction = functions.get(((ApplyType) itemId).getFunctionId()); |
| if (childFunction == null) { |
| // |
| // NO function defined |
| // |
| logger.warn("no function defined for apply being added."); |
| } else { |
| // |
| // Add its children |
| // |
| this.initializeChildren((ApplyType) itemId, childFunction); |
| } |
| } else if (itemId instanceof AttributeValueType) { |
| // |
| this.values.put((AttributeValueType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createAttributeValue((AttributeValueType) itemId)); |
| // |
| } else if (itemId instanceof AttributeDesignatorType) { |
| // |
| this.designators.put((AttributeDesignatorType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createAttributeDesignator((AttributeDesignatorType) itemId)); |
| // |
| } else if (itemId instanceof AttributeSelectorType) { |
| // |
| this.selectors.put((AttributeSelectorType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createAttributeSelector((AttributeSelectorType) itemId)); |
| // |
| } else if (itemId instanceof VariableReferenceType) { |
| // |
| this.variables.put((VariableReferenceType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createVariableReference((VariableReferenceType) itemId)); |
| // |
| } else if (itemId instanceof FunctionType) { |
| // |
| this.functions.put((FunctionType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createFunction((FunctionType) itemId)); |
| // |
| } else if (itemId instanceof ExpressionType) { |
| // |
| this.expressions.put((ExpressionType) itemId, new ApplyParent(parent, argument)); |
| parent.getExpression().add(new ObjectFactory().createExpression((ExpressionType) itemId)); |
| } else { |
| logger.error("unknown itemId class: " + itemId.getClass().getCanonicalName()); |
| return null; |
| } |
| // |
| // Notify |
| // |
| this.fireItemSetChange(); |
| return new ExpressionItem(itemId); |
| } |
| |
| private JAXBElement<?> createElement(Object item) { |
| if (item instanceof ApplyType) { |
| return new ObjectFactory().createApply((ApplyType) item); |
| } else if (item instanceof AttributeValueType) { |
| return new ObjectFactory().createAttributeValue((AttributeValueType) item); |
| } else if (item instanceof AttributeDesignatorType) { |
| return new ObjectFactory().createAttributeDesignator((AttributeDesignatorType) item); |
| } else if (item instanceof AttributeSelectorType) { |
| return new ObjectFactory().createAttributeSelector((AttributeSelectorType) item); |
| } else if (item instanceof VariableReferenceType) { |
| return new ObjectFactory().createVariableReference((VariableReferenceType) item); |
| } else if (item instanceof FunctionType) { |
| return new ObjectFactory().createFunction((FunctionType) item); |
| } else if (item instanceof ExpressionType) { |
| return new ObjectFactory().createExpression((ExpressionType) item); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean addContainerProperty(Object propertyId, Class<?> type, |
| Object defaultValue) throws UnsupportedOperationException { |
| return false; |
| } |
| |
| @Override |
| public boolean removeContainerProperty(Object propertyId) |
| throws UnsupportedOperationException { |
| return false; |
| } |
| |
| @Override |
| public boolean removeAllItems() throws UnsupportedOperationException { |
| if (logger.isTraceEnabled()) { |
| logger.trace("removeAllItems: "); |
| } |
| boolean result = this.doRemoveAllItems(); |
| if (result == false) { |
| return false; |
| } |
| // |
| // Notify |
| // |
| this.fireItemSetChange(); |
| // |
| // Done |
| // |
| return true; |
| } |
| |
| public boolean doRemoveAllItems() throws UnsupportedOperationException { |
| if (logger.isTraceEnabled()) { |
| logger.trace("doRemoveAllItems: "); |
| } |
| // |
| // Removing the root item, make sure its removed from |
| // the parent. |
| // |
| if (this.parent instanceof ConditionType) { |
| ((ConditionType) this.parent).setExpression(null); |
| } else if (this.parent instanceof VariableDefinitionType) { |
| ((VariableDefinitionType) this.parent).setExpression(null); |
| } else if (this.parent instanceof AttributeAssignmentExpressionType) { |
| ((AttributeAssignmentExpressionType) this.parent).setExpression(null); |
| } else if (this.parent instanceof ApplyType) { |
| // |
| // TODO ?? Special case |
| // |
| return false; |
| } else { |
| return false; |
| } |
| // |
| // Null our root |
| // |
| this.root = null; |
| // |
| // Clear out our maps |
| // |
| this.applys.clear(); |
| this.designators.clear(); |
| this.functions.clear(); |
| this.values.clear(); |
| this.selectors.clear(); |
| this.variables.clear(); |
| this.expressions.clear(); |
| // |
| // Done |
| // |
| return true; |
| } |
| |
| @Override |
| public Collection<?> getChildren(Object itemId) { |
| final Collection<Object> items = new ArrayList<Object>(); |
| if (itemId instanceof ApplyType) { |
| items.addAll(this.getChildrenIds((ApplyType) itemId, false)); |
| } |
| if (logger.isTraceEnabled()) { |
| logger.trace("getChildren " + itemId + " (" + items.size() + "):" + items); |
| } |
| return Collections.unmodifiableCollection(items); |
| } |
| |
| public FunctionArgument getArgument(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("getArgument: " + itemId); |
| } |
| // |
| // First check if its a root |
| // |
| if (this.isRoot(itemId)) { |
| return null; |
| } |
| // |
| // Not a root - should be in the maps |
| // |
| if (itemId instanceof ApplyType) { |
| return this.applys.get(itemId).getArgument(); |
| } |
| if (itemId instanceof AttributeValueType) { |
| return this.values.get(itemId).getArgument(); |
| } |
| if (itemId instanceof AttributeDesignatorType) { |
| return this.designators.get(itemId).getArgument(); |
| } |
| if (itemId instanceof AttributeSelectorType) { |
| return this.selectors.get(itemId).getArgument(); |
| } |
| if (itemId instanceof VariableReferenceType) { |
| return this.variables.get(itemId).getArgument(); |
| } |
| if (itemId instanceof FunctionType) { |
| return this.functions.get(itemId).getArgument(); |
| } |
| if (itemId instanceof ExpressionType) { |
| return this.expressions.get(itemId).getArgument(); |
| } |
| return null; |
| } |
| |
| @Override |
| public Object getParent(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("getParent: " + itemId); |
| } |
| // |
| // First check if its a root |
| // |
| if (this.isRoot(itemId)) { |
| return null; |
| } |
| // |
| // Not a root - should be in the maps |
| // |
| if (itemId instanceof ApplyType) { |
| return this.applys.get(itemId).getApply(); |
| } |
| if (itemId instanceof AttributeValueType) { |
| return this.values.get(itemId).getApply(); |
| } |
| if (itemId instanceof AttributeDesignatorType) { |
| return this.designators.get(itemId).getApply(); |
| } |
| if (itemId instanceof AttributeSelectorType) { |
| return this.selectors.get(itemId).getApply(); |
| } |
| if (itemId instanceof VariableReferenceType) { |
| return this.variables.get(itemId).getApply(); |
| } |
| if (itemId instanceof FunctionType) { |
| return this.functions.get(itemId).getApply(); |
| } |
| if (itemId instanceof ExpressionType) { |
| return this.expressions.get(itemId).getApply(); |
| } |
| return null; |
| } |
| |
| @Override |
| public Collection<?> rootItemIds() { |
| final Collection<Object> items = new ArrayList<Object>(); |
| if (this.root != null) { |
| items.add(this.root); |
| } |
| if (logger.isTraceEnabled()) { |
| logger.trace("rootItemIds " + " (" + items.size() + "):" + items); |
| } |
| return Collections.unmodifiableCollection(items); |
| } |
| |
| @Override |
| public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException { |
| // |
| // TODO we can support this later |
| // |
| throw new UnsupportedOperationException("Should we support this? Can be tricky. Most likely user dragging an item from one area to another. For now, use removeItem, addItem."); |
| } |
| |
| @Override |
| public boolean areChildrenAllowed(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("areChildrenAllowed: " + itemId); |
| } |
| if (itemId instanceof ApplyType) { |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) |
| throws UnsupportedOperationException { |
| if (itemId instanceof ApplyType && areChildrenAllowed) { |
| return true; |
| } |
| if (! areChildrenAllowed) { |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean isRoot(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("isRoot: " + itemId); |
| } |
| if (itemId == null) { |
| logger.error("isRoot itemId is NULL"); |
| } |
| return this.root == itemId; |
| } |
| |
| @Override |
| public boolean hasChildren(Object itemId) { |
| if (logger.isTraceEnabled()) { |
| logger.trace("hasChildren: " + itemId); |
| } |
| if (itemId instanceof ApplyType) { |
| return ((ApplyType)itemId).getExpression().size() > 0; |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean removeItem(Object itemId) throws UnsupportedOperationException { |
| if (logger.isTraceEnabled()) { |
| logger.trace("removeItem: " + itemId); |
| } |
| // |
| // Check if they are removing the root |
| // |
| if (this.root == itemId) { |
| // |
| // Removing the root item, make sure its removed from |
| // the parent. |
| // |
| boolean result = this.doRemoveAllItems(); |
| if (result == false) { |
| return false; |
| } |
| // |
| // Notify |
| // |
| this.fireItemSetChange(); |
| return true; |
| } |
| // |
| // There should be a parent |
| // |
| ApplyParent parent = null; |
| // |
| // Remove the item from the maps |
| // |
| if (itemId instanceof ApplyType) { |
| parent = this.applys.get(itemId); |
| if (parent == null) { |
| return false; |
| } |
| if (this.applys.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof AttributeValueType) { |
| parent = this.values.get(itemId); |
| if (this.values.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof AttributeDesignatorType) { |
| parent = this.designators.get(itemId); |
| if (this.designators.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof AttributeSelectorType) { |
| parent = this.selectors.get(itemId); |
| if (this.selectors.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof VariableReferenceType) { |
| parent = this.variables.get(itemId); |
| if (this.variables.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof FunctionType) { |
| parent = this.functions.get(itemId); |
| if (this.functions.remove(itemId) == null) { |
| return false; |
| } |
| } else if (itemId instanceof ExpressionType) { |
| parent = this.expressions.get(itemId); |
| if (this.expressions.remove(itemId) != null) { |
| return false; |
| } |
| } else { |
| return false; |
| } |
| // |
| // Remove it from the parent Apply |
| // |
| boolean removed = false; |
| for (JAXBElement<?> element : parent.getApply().getExpression()) { |
| if (element.getValue().equals(itemId)) { |
| if (parent.getApply().getExpression().remove(element)) { |
| removed = true; |
| break; |
| } |
| break; |
| } |
| } |
| if (! removed) { |
| // |
| // Out of sync |
| // |
| logger.warn("Removing item from parent returned false, although we were able to remove it from our maps."); |
| } |
| // |
| // Notify |
| // |
| this.fireItemSetChange(); |
| return true; |
| } |
| |
| public class ExpressionItem implements Item { |
| private static final long serialVersionUID = 1L; |
| private final Object data; |
| |
| public ExpressionItem(Object data) { |
| this.data = data; |
| } |
| |
| public String getName() { |
| if (this.data instanceof ApplyType) { |
| if (((ApplyType) this.data).getDescription() != null) { |
| return "Apply - " + ((ApplyType) this.data).getDescription(); |
| } |
| return "Apply"; |
| } |
| if (this.data instanceof AttributeValueType) { |
| return "Attribute Value"; |
| } |
| if (this.data instanceof AttributeDesignatorType) { |
| return "Attribute Designator"; |
| } |
| if (this.data instanceof AttributeSelectorType) { |
| return "Attribute Selector"; |
| } |
| if (this.data instanceof VariableReferenceType) { |
| return "Variable Reference"; |
| } |
| if (this.data instanceof FunctionType) { |
| return "Function"; |
| } |
| if (this.data instanceof ExpressionType) { |
| return "<Argument Placeholder>"; |
| } |
| return null; |
| } |
| |
| public String getId() { |
| if (this.data instanceof ApplyType) { |
| return ((ApplyType) this.data).getFunctionId(); |
| } |
| if (this.data instanceof AttributeValueType) { |
| StringBuilder builder = new StringBuilder(); |
| for (Object content : ((AttributeValueType) this.data).getContent()) { |
| builder.append(content); |
| } |
| return builder.toString(); |
| } |
| if (this.data instanceof AttributeDesignatorType) { |
| return ((AttributeDesignatorType) this.data).getAttributeId(); |
| } |
| if (this.data instanceof AttributeSelectorType) { |
| return ((AttributeSelectorType) this.data).getPath(); |
| } |
| if (this.data instanceof VariableReferenceType) { |
| return ((VariableReferenceType) this.data).getVariableId(); |
| } |
| if (this.data instanceof FunctionType) { |
| return ((FunctionType) this.data).getFunctionId(); |
| } |
| return null; |
| } |
| |
| public String getIdShort() { |
| String id = this.getId(); |
| if (id == null) { |
| return id; |
| } |
| // |
| // Make it short |
| // |
| String[] parts = id.split("[:]"); |
| |
| if (parts != null && parts.length > 0) { |
| return parts[parts.length - 1]; |
| } |
| return id; |
| } |
| |
| public String getDatatype() { |
| if (this.data instanceof ApplyType) { |
| |
| Map<String, FunctionDefinition> map = JPAUtils.getFunctionIDMap(); |
| FunctionDefinition function = map.get(((ApplyType) this.data).getFunctionId()); |
| if (function != null) { |
| return function.getDatatypeBean().getXacmlId(); |
| } |
| } |
| if (this.data instanceof AttributeValueType) { |
| return ((AttributeValueType) this.data).getDataType(); |
| } |
| if (this.data instanceof AttributeDesignatorType) { |
| return ((AttributeDesignatorType) this.data).getDataType(); |
| } |
| if (this.data instanceof AttributeSelectorType) { |
| return ((AttributeSelectorType) this.data).getDataType(); |
| } |
| |
| /* |
| if (this.data instanceof VariableReferenceType) { |
| if (this.function instanceof FunctionArgument) { |
| return ((FunctionArgument) this.function).getDatatypeBean().getXacmlId(); |
| } |
| } |
| */ |
| /* |
| if (this.data instanceof FunctionType) { |
| if (this.function instanceof FunctionArgument) { |
| return ((FunctionArgument) this.function).getDatatypeBean().getXacmlId(); |
| } |
| } |
| */ |
| return null; |
| } |
| |
| public String getDatatypeShort() { |
| String dt = this.getDatatype(); |
| if (dt == null) { |
| return dt; |
| } |
| // |
| // Get short part |
| // |
| int index = dt.lastIndexOf('#'); |
| if (index == -1) { |
| String[] parts = dt.split("[:]"); |
| |
| if (parts != null && parts.length > 0) { |
| return parts[parts.length - 1]; |
| } |
| } else { |
| return dt.substring(index + 1); |
| } |
| return dt; |
| } |
| |
| @Override |
| public Property<?> getItemProperty(Object id) { |
| return getContainerProperty(this.data, id); |
| } |
| @Override |
| public Collection<?> getItemPropertyIds() { |
| return getContainerPropertyIds(); |
| } |
| @Override |
| public boolean addItemProperty(Object id, @SuppressWarnings("rawtypes") Property property) throws UnsupportedOperationException { |
| throw new UnsupportedOperationException("Expression container does not support adding new properties"); |
| } |
| @Override |
| public boolean removeItemProperty(Object id) throws UnsupportedOperationException { |
| throw new UnsupportedOperationException("Expression container does not support removing properties"); |
| } |
| } |
| } |