/** * * 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 com.agfa.hap.sdo; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry; /** * Helper class for {@link SelectClause} that represents * a comma-separated list of properties in a structured form. * @author AMOCZ * */ public abstract class PropertyTree { public abstract String asCommmaSeparatedString(); public abstract PropertyTree getProperty(String property); public abstract PropertyTree getProperty(Property property); public abstract boolean containsProperty(Property property); public abstract boolean containsProperty(String property); public static PropertyTree newPropertyTree(Type type, String selectClause) { PropertyTree result = new MapBasedPropertyTree(type); String[] parts = selectClause.split(","); for (String part : parts) { if (part.length() > 0) { result = result.extend(part); } } return result; } protected PropertyTree extend(String property) { property = property.trim(); int index = property.indexOf('.'); if (index < 0) { if (property.length() == 1 && property.charAt(0) == '*') { return STAR_PROPERTYTREE; } if (property.length() == 2 && property.charAt(0) == '*' && property.charAt(1) == '*') { return STARSTAR_PROPERTYTREE; } addSimpleProperty(property); } else { addComposedProperty(property.substring(0, index), property.substring(index+1)); } return this; } protected void addSimpleProperty(String propertyName) { // ok } protected void addComposedProperty(String ownerName, String childName) { // ok } final static PropertyTree EMPTY_PROPERTYTREE = new PropertyTree() { public PropertyTree getProperty(String property) { return null; } public PropertyTree getProperty(Property property) { return null; } public boolean containsProperty(Property property) { return false; } public boolean containsProperty(String property) { return false; } @Override public String asCommmaSeparatedString() { return ""; } }; final static PropertyTree STAR_PROPERTYTREE = new PropertyTree() { public PropertyTree getProperty(String property) { return EMPTY_PROPERTYTREE; } public PropertyTree getProperty(Property property) { return EMPTY_PROPERTYTREE; } public boolean containsProperty(Property property) { return true; } public boolean containsProperty(String property) { return true; } @Override public String asCommmaSeparatedString() { throw new UnsupportedOperationException(); } }; final static PropertyTree STARSTAR_PROPERTYTREE = new PropertyTree() { public PropertyTree getProperty(String property) { return this; } public PropertyTree getProperty(Property property) { return this; } public boolean containsProperty(Property property) { return true; } public boolean containsProperty(String property) { return true; } @Override public String asCommmaSeparatedString() { throw new UnsupportedOperationException(); } }; static class MapBasedPropertyTree extends PropertyTree { private Map properties; private Type type; public MapBasedPropertyTree(Type type) { this.type = type; properties = new HashMap(); } public Type getType() { return type; } public Set> getProperties() { return properties.entrySet(); } public PropertyTree getProperty(String property) { return properties.get(type.getProperty(property)); } public PropertyTree getProperty(Property property) { return properties.get(property); } public boolean containsProperty(Property property) { return properties.containsKey(property); } public boolean containsProperty(String property) { return properties.containsKey(type.getProperty(property)); } @Override protected void addSimpleProperty(String property) { Property prop = type.getProperty(property); if (prop == null) { throw new IllegalArgumentException("Unknown property " + property + " in type " + type.getName()); } if (!prop.getType().isDataType() && !properties.containsKey(prop)) { properties.put(prop, new MapBasedPropertyTree(prop.getType())); } } @Override protected void addComposedProperty(String owner, String child) { Property prop = type.getProperty(owner); if (prop == null) { throw new IllegalArgumentException("Unknown property " + owner + " in type " + type.getName()); } if (!prop.getType().isDataType()) { PropertyTree children = properties.get(prop); if (children == null) { children = newPropertyTree(prop.getType(), child); properties.put(prop, children); } else { children.extend(child); } } } public Collection propertyPaths() { Collection paths = new ArrayList(); for (Entry entry : this.getProperties()){ String rootPropName = entry.getKey().getName(); MapBasedPropertyTree tree = (MapBasedPropertyTree) entry.getValue(); Collection childPaths = tree.propertyPaths(); if (childPaths.isEmpty()){ paths.add(rootPropName); } else { for (String childPath : childPaths){ paths.add(rootPropName + "." + childPath); } } } return paths; } public String asCommmaSeparatedString(){ StringBuilder builder = new StringBuilder(); for(String path : this.propertyPaths()){ builder.append(path); builder.append(','); } builder.setLength(builder.length()-1); //remove last , return builder.toString(); } } }