You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openaz.apache.org by pd...@apache.org on 2016/03/17 02:15:38 UTC
[16/23] incubator-openaz git commit: Ported original att source to
openaz This Closes #3
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java
new file mode 100644
index 0000000..961984e
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/RuleAlgorithms.java
@@ -0,0 +1,115 @@
+/*
+ * 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.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.openaz.xacml.api.Identifier;
+
+@Entity
+@Table(name="RuleAlgorithms")
+@NamedQuery(name="RuleAlgorithms.findAll", query="SELECT d FROM RuleAlgorithms d")
+public class RuleAlgorithms implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public static final char STANDARD = 'S';
+ public static final char CUSTOM = 'C';
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name="id")
+ private int id;
+
+ @Column(name="is_standard", nullable=false)
+ private char isStandard;
+
+ @Column(name="xacml_id", nullable=false, unique=true, length=255)
+ private String xacmlId;
+
+ @Column(name="short_name", nullable=false, length=64)
+ private String shortName;
+
+ public RuleAlgorithms(Identifier id, char standard) {
+ if (id != null) {
+ this.xacmlId = id.stringValue();
+ }
+ this.isStandard = standard;
+ }
+ public RuleAlgorithms(Identifier id) {
+ this(id, RuleAlgorithms.STANDARD);
+ }
+
+ public RuleAlgorithms() {
+ this(null, RuleAlgorithms.STANDARD);
+ }
+
+ public int getId() {
+ return this.id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public char getIsStandard() {
+ return this.isStandard;
+ }
+
+ public void setIsStandard(char isStandard) {
+ this.isStandard = isStandard;
+ }
+
+ @Transient
+ public boolean isStandard() {
+ return this.isStandard == RuleAlgorithms.STANDARD;
+ }
+
+ @Transient
+ public boolean isCustom() {
+ return this.isStandard == RuleAlgorithms.CUSTOM;
+ }
+
+ public String getXacmlId() {
+ return this.xacmlId;
+ }
+
+ public void setXacmlId(String xacmlId) {
+ this.xacmlId = xacmlId;
+ }
+
+ public String getShortName() {
+ return shortName;
+ }
+
+ public void setShortName(String shortName) {
+ this.shortName = shortName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java
new file mode 100644
index 0000000..85d06f5
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/jpa/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ *
+ */
+/**
+ * @author pameladragosh
+ *
+ */
+package org.apache.openaz.xacml.admin.jpa;
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java
new file mode 100644
index 0000000..37d2fd4
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeContainer.java
@@ -0,0 +1,500 @@
+/*
+ * 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.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.util.JPAUtils;
+import org.apache.openaz.xacml.api.AttributeValue;
+import org.apache.openaz.xacml.api.Identifier;
+import org.apache.openaz.xacml.util.XACMLPolicyAggregator;
+import org.apache.openaz.xacml.util.XACMLPolicyScanner;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+import com.vaadin.ui.Table;
+
+public class AttributeContainer extends ItemSetChangeNotifier implements Container.Hierarchical, Container.ItemSetChangeNotifier {
+ private static final long serialVersionUID = 1L;
+ private static Log logger = LogFactory.getLog(AttributeContainer.class);
+ //private final AttributeContainer self = this;
+ private final Map<Category, Map<Datatype, Map<String, Set<ContainerAttribute>>>> mapAttributes = new HashMap<Category, Map<Datatype, Map<String, Set<ContainerAttribute>>>>();
+
+ class ContainerAttribute {
+ Path policy;
+ boolean isRoot;
+ AttributeValue<?> value;
+
+ public ContainerAttribute(Path policy, boolean isRoot, AttributeValue<?> value) {
+ this.policy = policy;
+ this.isRoot = isRoot;
+ this.value = value;
+ }
+
+ public Path getPolicy() {
+ return policy;
+ }
+
+ public boolean isRoot() {
+ return isRoot;
+ }
+
+ public AttributeValue<?> getValue() {
+ return value;
+ }
+
+ public boolean isCustom() {
+ return this.policy == null;
+ }
+ }
+ /**
+ * String identifier of an object's "id" property.
+ */
+ public static String PROPERTY_ID = "Id";
+
+ /**
+ * String identifier of an object's "category" property.
+ */
+ public static String PROPERTY_CATEGORY = "Category";
+
+ /**
+ * String identifier of an object's "datatype" property.
+ */
+ public static String PROPERTY_DATATYPE = "Datatype";
+
+ /**
+ * String identifier of an object's "value" property.
+ */
+ public static String PROPERTY_VALUES = "Values";
+
+ /**
+ * List of the string identifiers for the available properties.
+ */
+ public static Collection<String> ATTRIBUTE_PROPERTIES;
+
+ private final static Method ATTRIBUTEITEM_ID;
+ private final static Method ATTRIBUTEITEM_CATEGORY;
+ private final static Method ATTRIBUTEITEM_DATATYPE;
+ private final static Method ATTRIBUTEITEM_VALUES;
+ static {
+ ATTRIBUTE_PROPERTIES = new ArrayList<String>();
+ ATTRIBUTE_PROPERTIES.add(PROPERTY_ID);
+ ATTRIBUTE_PROPERTIES.add(PROPERTY_CATEGORY);
+ ATTRIBUTE_PROPERTIES.add(PROPERTY_DATATYPE);
+ ATTRIBUTE_PROPERTIES.add(PROPERTY_VALUES);
+ ATTRIBUTE_PROPERTIES = Collections.unmodifiableCollection(ATTRIBUTE_PROPERTIES);
+ try {
+ ATTRIBUTEITEM_ID = AttributeItem.class.getMethod("getId", new Class[]{});
+ ATTRIBUTEITEM_CATEGORY = AttributeItem.class.getMethod("getCategory", new Class[]{});
+ ATTRIBUTEITEM_DATATYPE = AttributeItem.class.getMethod("getDatatype", new Class[]{});
+ ATTRIBUTEITEM_VALUES = AttributeItem.class.getMethod("getValues", new Class[]{});
+ } catch (final NoSuchMethodException e) {
+ throw new RuntimeException("Internal error finding methods in AttributeContainer");
+ }
+ }
+
+ public AttributeContainer(Path rootPolicy, Collection<Path> referencedPolicies) {
+ super();
+ this.setContainer(this);
+ this.initialize(rootPolicy, referencedPolicies);
+ }
+
+ protected void initialize(Path rootPolicy, Collection<Path> referencedPolicies) {
+ XACMLPolicyAggregator aggregator = new XACMLPolicyAggregator();
+ //
+ // Scan the policy
+ //
+ new XACMLPolicyScanner(rootPolicy, aggregator).scan();
+ this.addAttributes(aggregator, rootPolicy, true);
+ aggregator = new XACMLPolicyAggregator();
+ //
+ // Scan the referenced policies
+ //
+ for (Path policy : referencedPolicies) {
+ new XACMLPolicyScanner(policy, aggregator).scan();
+ this.addAttributes(aggregator, policy, false);
+ aggregator = new XACMLPolicyAggregator();
+ }
+ }
+
+ protected void addAttributes(XACMLPolicyAggregator aggregator, Path policy, boolean isRoot) {
+ for (Identifier cat : aggregator.getAttributeMap().keySet()) {
+ Category category = JPAUtils.findCategory(cat);
+ if (category == null) {
+ logger.warn("Could not find category: " + cat);
+ continue;
+ }
+ if (this.mapAttributes.containsKey(category) == false) {
+ this.mapAttributes.put(category, new HashMap<Datatype, Map<String, Set<ContainerAttribute>>>());
+ }
+ Map<Datatype, Map<String, Set<ContainerAttribute>>> datatypeMap = this.mapAttributes.get(category);
+ for (Identifier dt : aggregator.getAttributeMap().get(cat).keySet()) {
+ Datatype datatype = JPAUtils.findDatatype(dt);
+ if (datatype == null) {
+ logger.warn("Could not find datatype: " + dt);
+ }
+ //
+ // Need a unique datatype object
+ //
+ datatype = new Datatype((int) System.currentTimeMillis(), datatype);
+ if (datatypeMap.containsKey(datatype) == false) {
+ datatypeMap.put(datatype, new HashMap<String, Set<ContainerAttribute>>());
+ }
+ Map<String, Set<ContainerAttribute>> attributeMap = datatypeMap.get(datatype);
+ for (Identifier id : aggregator.getAttributeMap().get(cat).get(dt).keySet()) {
+ if (attributeMap.containsKey(id.stringValue()) == false) {
+ attributeMap.put(id.stringValue(), new HashSet<ContainerAttribute>());
+ }
+ for (AttributeValue<?> attribute : aggregator.getAttributeMap().get(cat).get(dt).get(id)) {
+ attributeMap.get(id.stringValue()).add(new ContainerAttribute(policy, isRoot, attribute));
+ }
+ }
+ }
+ }
+ }
+
+ protected boolean isObjectSupported(Object itemId) {
+ if (itemId instanceof Category ||
+ itemId instanceof Datatype ||
+ itemId instanceof String ||
+ itemId instanceof ContainerAttribute) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Item getItem(Object itemId) {
+ if (this.isObjectSupported(itemId)) {
+ return new AttributeItem(itemId);
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<?> getContainerPropertyIds() {
+ return ATTRIBUTE_PROPERTIES;
+ }
+
+ @Override
+ public Collection<?> getItemIds() {
+ final Collection<Object> items = new ArrayList<Object>();
+ for (Category category : this.mapAttributes.keySet()) {
+ items.add(category);
+ for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+ items.add(datatype);
+ for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+ items.add(id);
+ for (ContainerAttribute attribute : this.mapAttributes.get(category).get(datatype).get(id)) {
+ items.add(attribute);
+ }
+ }
+ }
+ }
+ return Collections.unmodifiableCollection(items);
+ }
+
+ @Override
+ public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ if (propertyId.equals(PROPERTY_ID)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeItem(itemId), ATTRIBUTEITEM_ID, null);
+ }
+ if (propertyId.equals(PROPERTY_CATEGORY)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeItem(itemId), ATTRIBUTEITEM_CATEGORY, null);
+ }
+ if (propertyId.equals(PROPERTY_DATATYPE)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeItem(itemId), ATTRIBUTEITEM_DATATYPE, null);
+ }
+ if (propertyId.equals(PROPERTY_VALUES)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeItem(itemId), ATTRIBUTEITEM_VALUES, null);
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ if (propertyId.equals(PROPERTY_ID)) {
+ return String.class;
+ }
+ if (propertyId.equals(PROPERTY_CATEGORY)) {
+ return Category.class;
+ }
+ if (propertyId.equals(PROPERTY_DATATYPE)) {
+ return Datatype.class;
+ }
+ if (propertyId.equals(PROPERTY_VALUES)) {
+ return Table.class;
+ }
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return this.mapAttributes.size();
+ }
+
+ @Override
+ public boolean containsId(Object itemId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return false;
+ }
+ if (itemId instanceof Category) {
+ return this.mapAttributes.containsKey(itemId);
+ }
+ for (Category category : this.mapAttributes.keySet()) {
+ if (itemId instanceof Datatype) {
+ return this.mapAttributes.get(category).containsKey(itemId);
+ }
+ for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+ if (itemId instanceof String) {
+ return this.mapAttributes.get(category).get(datatype).containsKey(itemId);
+ }
+ for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+ if (itemId instanceof ContainerAttribute) {
+ return this.mapAttributes.get(category).get(datatype).get(id).contains(itemId);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Item addItem(Object itemId) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Use addItem(Category, Datatype, AttributeValue<?>) instead.");
+ }
+
+ @Override
+ public Object addItem() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Use addItem(Category, Datatype, AttributeValue<?>) instead.");
+ }
+
+ @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 {
+ throw new UnsupportedOperationException("Can't remove all the items. You can remove custom user attributes.");
+ }
+
+ @Override
+ public Collection<?> getChildren(Object itemId) {
+ //
+ // PLD TODO - this may not work for Datatype
+ //
+ final Collection<Object> items = new ArrayList<Object>();
+ for (Category category : this.mapAttributes.keySet()) {
+ for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+ if (itemId instanceof Category) {
+ items.add(datatype);
+ }
+ for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+ if (itemId instanceof Category ||
+ itemId instanceof Datatype) {
+ items.add(id);
+ items.addAll(this.mapAttributes.get(category).get(datatype).get(id));
+ } else if (itemId instanceof String) {
+ items.addAll(this.mapAttributes.get(category).get(datatype).get(id));
+ }
+ }
+ }
+ }
+ return Collections.unmodifiableCollection(items);
+ }
+
+ @Override
+ public Object getParent(Object itemId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Collection<?> rootItemIds() {
+ final Collection<Object> items = new ArrayList<Object>();
+ items.add(this.mapAttributes.keySet());
+ return Collections.unmodifiableCollection(items);
+ }
+
+ @Override
+ public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Can't move attributes around. Use addItem(Category, Datatype, Attribute).");
+ }
+
+ @Override
+ public boolean areChildrenAllowed(Object itemId) {
+ if (itemId instanceof Category ||
+ itemId instanceof Datatype ||
+ itemId instanceof String) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
+ throws UnsupportedOperationException {
+ if (itemId instanceof Category ||
+ itemId instanceof Datatype ||
+ itemId instanceof String) {
+ if (areChildrenAllowed) {
+ return true;
+ }
+ return false;
+ }
+ if (areChildrenAllowed == false) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isRoot(Object itemId) {
+ return this.mapAttributes.containsKey(itemId);
+ }
+
+ @Override
+ public boolean hasChildren(Object itemId) {
+ if (itemId instanceof ContainerAttribute) {
+ return false;
+ }
+ if (itemId instanceof Category) {
+ if (this.mapAttributes.containsKey(itemId)) {
+ return this.mapAttributes.get(itemId).size() > 0;
+ }
+ return false;
+ }
+ //
+ // PLD TODO - this may not work. Datatype may prove difficult
+ // to distinguish which category it is in.
+ //
+ for (Category category : this.mapAttributes.keySet()) {
+ if (itemId instanceof Datatype) {
+ if (this.mapAttributes.get(category).containsKey(itemId)) {
+ return this.mapAttributes.get(category).get(itemId).size() > 0;
+ }
+ continue;
+ }
+ for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+ if (itemId instanceof String) {
+ if (this.mapAttributes.get(category).get(datatype).containsKey(itemId)) {
+ return this.mapAttributes.get(category).get(datatype).get(itemId).size() > 0;
+ }
+ continue;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean removeItem(Object itemId) throws UnsupportedOperationException {
+ if (! (itemId instanceof ContainerAttribute)) {
+ return false;
+ }
+ for (Category category : this.mapAttributes.keySet()) {
+ for (Datatype datatype : this.mapAttributes.get(category).keySet()) {
+ for (String id : this.mapAttributes.get(category).get(datatype).keySet()) {
+ if (this.mapAttributes.get(category).get(datatype).get(id).contains(itemId)) {
+ return this.mapAttributes.get(category).get(datatype).get(id).remove(itemId);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public class AttributeItem implements Item {
+ private static final long serialVersionUID = 1L;
+ private final Object data;
+
+ public AttributeItem(Object data) {
+ this.data = data;
+ }
+
+ public String getId() {
+ return null;
+ }
+
+ public Category getCategory() {
+ return null;
+ }
+
+ public Datatype getDatatype() {
+ return null;
+ }
+
+ public Table getValues() {
+ return null;
+ }
+
+ @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("Attribute container does not support adding new properties");
+ }
+ @Override
+ public boolean removeItemProperty(Object id) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Attribute container does not support removing properties");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java
new file mode 100644
index 0000000..1074936
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/AttributeValueContainer.java
@@ -0,0 +1,300 @@
+/*
+ * 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.List;
+
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.model.AttributeContainer.ContainerAttribute;
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.MethodProperty;
+
+public class AttributeValueContainer extends ItemSetChangeNotifier implements Container.Ordered, Container.ItemSetChangeNotifier {
+ private static final long serialVersionUID = 1L;
+ private final Datatype datatype; //NOPMD
+ private final List<ContainerAttribute> attributes;
+
+ /**
+ * String identifier of an object's "Value" property.
+ */
+ public static String PROPERTY_VALUE = "Value";
+
+ /**
+ * String identifier of an object's "Source" property.
+ */
+ public static String PROPERTY_SOURCE = "Source";
+
+ /**
+ * List of the string identifiers for the available properties.
+ */
+ public static Collection<String> ATTRIBUTEVALUE_PROPERTIES;
+
+ private final static Method ATTRIBUTEVALUEITEM_VALUE;
+ private final static Method ATTRIBUTEVALUEITEM_SOURCE;
+ static {
+ ATTRIBUTEVALUE_PROPERTIES = new ArrayList<String>();
+ ATTRIBUTEVALUE_PROPERTIES.add(PROPERTY_VALUE);
+ ATTRIBUTEVALUE_PROPERTIES.add(PROPERTY_SOURCE);
+ ATTRIBUTEVALUE_PROPERTIES = Collections.unmodifiableCollection(ATTRIBUTEVALUE_PROPERTIES);
+ try {
+ ATTRIBUTEVALUEITEM_VALUE = AttributeValueItem.class.getMethod("getValue", new Class[]{});
+ ATTRIBUTEVALUEITEM_SOURCE = AttributeValueItem.class.getMethod("getSource", new Class[]{});
+ } catch (final NoSuchMethodException e) {
+ throw new RuntimeException("Internal error finding methods in AttributeValueContainer");
+ }
+ }
+
+ public AttributeValueContainer(Datatype datatype, List<ContainerAttribute> attributes) {
+ this.datatype = datatype;
+ this.attributes = attributes;
+ }
+
+ public boolean isObjectSupported(Object itemId) {
+ return itemId instanceof ContainerAttribute;
+ }
+
+ @Override
+ public Item getItem(Object itemId) {
+ if (itemId instanceof ContainerAttribute) {
+ return new AttributeValueItem((ContainerAttribute) itemId);
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<?> getContainerPropertyIds() {
+ return ATTRIBUTEVALUE_PROPERTIES;
+ }
+
+ @Override
+ public Collection<?> getItemIds() {
+ return Collections.unmodifiableList(this.attributes);
+ }
+
+ @Override
+ public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ if (propertyId.equals(PROPERTY_VALUE)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeValueItem((ContainerAttribute) itemId), ATTRIBUTEVALUEITEM_VALUE, null);
+ }
+
+ if (propertyId.equals(PROPERTY_SOURCE)) {
+ return new MethodProperty<Object>(getType(propertyId),
+ new AttributeValueItem((ContainerAttribute) itemId), ATTRIBUTEVALUEITEM_SOURCE, null);
+ }
+ return null;
+ }
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ if (propertyId.equals(PROPERTY_VALUE)) {
+ return String.class;
+ }
+ if (propertyId.equals(PROPERTY_SOURCE)) {
+ return String.class;
+ }
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return this.attributes.size();
+ }
+
+ @Override
+ public boolean containsId(Object itemId) {
+ return this.attributes.contains(itemId);
+ }
+
+ @Override
+ public Item addItem(Object itemId) throws UnsupportedOperationException {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ return new AttributeValueItem((ContainerAttribute) itemId);
+ }
+
+ @Override
+ public Object addItem() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Please use addItem(Object itemId) - setup the container attribute first.");
+ }
+
+ @Override
+ public boolean removeItem(Object itemId) throws UnsupportedOperationException {
+ if (this.isObjectSupported(itemId) == false) {
+ return false;
+ }
+ throw new UnsupportedOperationException("TODO");
+// return this.attributes.remove(itemId);
+ }
+
+ @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 {
+ throw new UnsupportedOperationException("TODO");
+// this.attributes.clear();
+// return true;
+ }
+
+ @Override
+ public Object nextItemId(Object itemId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ int index = this.getItemIndex((ContainerAttribute) itemId);
+ if (index == -1 || index >= this.attributes.size()) {
+ return null;
+ }
+ return this.attributes.get(index + 1);
+ }
+
+ @Override
+ public Object prevItemId(Object itemId) {
+ if (this.isObjectSupported(itemId) == false) {
+ return null;
+ }
+ int index = this.getItemIndex((ContainerAttribute) itemId);
+ if (index == -1 || index == 0) {
+ return null;
+ }
+ return this.attributes.get(index - 1);
+ }
+
+ @Override
+ public Object firstItemId() {
+ if (this.attributes.size() > 0) {
+ return this.attributes.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public Object lastItemId() {
+ if (this.attributes.size() > 0) {
+ return this.attributes.get(this.attributes.size() - 1);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isFirstId(Object itemId) {
+ if (this.attributes.size() > 0) {
+ return this.attributes.get(0).equals(itemId);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isLastId(Object itemId) {
+ if (this.attributes.size() > 0) {
+ return this.attributes.get(this.attributes.size() - 1).equals(itemId);
+ }
+ return false;
+ }
+
+ @Override
+ public Object addItemAfter(Object previousItemId) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Use addItemAfter(Object previousItemId, Object newItemId) - please create the object yourself.");
+ }
+
+ @Override
+ public Item addItemAfter(Object previousItemId, Object newItemId) throws UnsupportedOperationException {
+ if (this.isObjectSupported(previousItemId) == false || this.isObjectSupported(newItemId) == false) {
+ return null;
+ }
+ int index = this.getItemIndex((ContainerAttribute) previousItemId);
+ if (index >= 0) {
+ this.attributes.add(index, (ContainerAttribute) newItemId);
+ }
+ return null;
+ }
+
+ protected int getItemIndex(ContainerAttribute itemId) {
+ int index;
+ for (index = 0; index < this.attributes.size(); index++) {
+ if (this.attributes.get(index).equals(itemId)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ public class AttributeValueItem implements Item {
+ private static final long serialVersionUID = 1L;
+ private final ContainerAttribute attribute;
+
+ public AttributeValueItem(ContainerAttribute attribute) {
+ this.attribute = attribute;
+ }
+
+ public String getValue() {
+ if (this.attribute == null) {
+ return null;
+ }
+ return this.attribute.value.toString();
+ }
+
+ public String getSource() {
+ if (this.attribute == null) {
+ return null;
+ }
+ return this.attribute.value.toString();
+ }
+
+ @Override
+ public Property<?> getItemProperty(Object id) {
+ return getContainerProperty(this.attribute, id);
+ }
+ @Override
+ public Collection<?> getItemPropertyIds() {
+ return getContainerPropertyIds();
+ }
+ @Override
+ public boolean addItemProperty(Object id, @SuppressWarnings("rawtypes") Property property) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Attribute Value container does not support adding new properties");
+ }
+ @Override
+ public boolean removeItemProperty(Object id) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Attribute Value container does not support removing properties");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/648d0c0d/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java
new file mode 100644
index 0000000..30c8670
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/model/ExpressionContainer.java
@@ -0,0 +1,1215 @@
+/*
+ * 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");
+ }
+ }
+}