/* * $Id: NestedProperty.java,v 1.1 2007-02-27 12:45:29 eugen Exp $ * * Copyright (C) 2002 by Brockmann Consult (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation. This program is distributed in the hope it will * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.bc.util.prop; import java.util.HashMap; import java.util.Map; public class NestedProperty implements Property { private Property parent; private Property child; protected NestedProperty(Property parent, Property child) { setParent(parent); setChild(child); } public String getName() { if (child instanceof MapProperty) { final String childName = child.getName(); if (((MapProperty) child).isNameJavaIdentifier()) { return parent.getName() + "." + childName; } else { return parent.getName() + "[\"" + childName + "\"]"; // todo 3 nf/** - escape '"' } } else { return parent.getName() + "." + child.getName(); } } public Class getType() { return child.getType(); } public Property getParent() { return parent; } public void setParent(Property parent) { if (parent == null) { throw new IllegalArgumentException("parent is null"); } this.parent = parent; } public Property getChild() { return child; } public void setChild(Property child) { if (child == null) { throw new IllegalArgumentException("child is null"); } if (child instanceof NestedProperty) { throw new IllegalArgumentException("child is a NestedProperty"); } this.child = child; } public Object getValue(Object beanInstance) { final Object parentValue = parent.getValue(beanInstance); return child.getValue(parentValue); } public void setValue(Object beanInstance, Object value) { final Object parentValue = parent.getValue(beanInstance); child.setValue(parentValue, value); } public boolean isAssignable(Object beanInstance) { return child.isAssignable(beanInstance) && parent.isAssignable(beanInstance); } public void makeAssignable(Object beanInstance) { parent.makeAssignable(beanInstance); Object parentValue = parent.getValue(beanInstance); if (parentValue == null) { final Class parentType = parent.getType(); if (Map.class.equals(parentType)) { parentValue = new HashMap(); } else if (Property.UNKNOWN_TYPE.equals(parentType)) { parentValue = new HashMap(); } else { try { parentValue = parentType.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("failed to make property '" + getName() + "' assignable", e); } catch (IllegalAccessException e) { throw new RuntimeException("failed to make property '" + getName() + "' assignable", e); } } parent.setValue(beanInstance, parentValue); } child.makeAssignable(parentValue); } public String getTreeAsString() { return "NestedProperty["+parent.getTreeAsString()+","+child.getTreeAsString()+"]"; } }