/* $Id$ */ /** * 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.manifoldcf.scriptengine; import org.apache.manifoldcf.core.interfaces.*; import java.util.*; /** Variable wrapper for ConfigurationNode object. */ public class VariableConfigurationNode extends VariableBase { protected ConfigurationNode configurationNode; public VariableConfigurationNode(String name) { configurationNode = new ConfigurationNode(name); } public VariableConfigurationNode(ConfigurationNode node) { configurationNode = node; } /** Check if the variable has a script value */ @Override public boolean hasScriptValue() throws ScriptException { return true; } /** Get the variable's script value */ @Override public String getScriptValue() throws ScriptException { StringBuilder sb = new StringBuilder(); sb.append("<< "); sb.append(new VariableString(configurationNode.getType()).getScriptValue()); sb.append(" : "); String valueField = configurationNode.getValue(); if (valueField == null) valueField = ""; sb.append(new VariableString(valueField).getScriptValue()); sb.append(" : "); boolean needComma = false; Iterator<String> iter = configurationNode.getAttributes(); String[] attrs = new String[configurationNode.getAttributeCount()]; int i = 0; while (iter.hasNext()) { String attrName = iter.next(); attrs[i++] = attrName; } java.util.Arrays.sort(attrs); i = 0; while (i < attrs.length) { String attrName = attrs[i++]; String value = configurationNode.getAttributeValue(attrName); if (needComma) sb.append(", "); else needComma = true; sb.append(new VariableString(attrName).getScriptValue()); sb.append("="); sb.append(new VariableString(value).getScriptValue()); } sb.append(" : "); i = 0; while (i < configurationNode.getChildCount()) { ConfigurationNode child = configurationNode.findChild(i); if (i > 0) sb.append(", "); sb.append(new VariableConfigurationNode(child).getScriptValue()); i++; } sb.append(" >>"); return sb.toString(); } /** Check if the variable has a string value */ @Override public boolean hasStringValue() throws ScriptException { return true; } /** Convert to a value */ @Override public String getStringValue() throws ScriptException { if (configurationNode.getValue() == null) return ""; return configurationNode.getValue(); } /** Get the variable's value as a ConfigurationNode object */ public ConfigurationNode getConfigurationNodeValue() throws ScriptException { return configurationNode; } /** Get a named attribute of the variable; e.g. xxx.yyy */ @Override public VariableReference getAttribute(String attributeName) throws ScriptException { // We recognize the __size__ attribute if (attributeName.equals(ATTRIBUTE_SIZE)) return new VariableInt(configurationNode.getChildCount()); // Also, the __type__ attribute if (attributeName.equals(ATTRIBUTE_TYPE)) return new VariableString(configurationNode.getType()); // And the __value__ attribute if (attributeName.equals(ATTRIBUTE_VALUE)) return new ValueReference(); if (attributeName.equals(ATTRIBUTE_DICT)) { VariableDict dict = new VariableDict(); int i = 0; while (i < configurationNode.getChildCount()) { ConfigurationNode child = configurationNode.findChild(i++); String type = child.getType(); dict.getIndexed(new VariableString(type)).setReference(new VariableConfigurationNode(child)); } return dict; } if (attributeName.equals(ATTRIBUTE_SCRIPT) || attributeName.equals(ATTRIBUTE_STRING) || attributeName.equals(ATTRIBUTE_INT) || attributeName.equals(ATTRIBUTE_FLOAT) || attributeName.equals(ATTRIBUTE_BOOLEAN)) return super.getAttribute(attributeName); // All others are presumed to be attributes of the configuration node, which can be set or cleared. return new AttributeReference(attributeName); } /** Get an indexed property of the variable */ @Override public VariableReference getIndexed(Variable index) throws ScriptException { if (index == null) throw new ScriptException(composeMessage("Subscript cannot be null")); int indexValue = index.getIntValue(); if (indexValue >= 0 && indexValue < configurationNode.getChildCount()) return new NodeReference(indexValue); throw new ScriptException(composeMessage("Subscript is out of bounds: "+indexValue)); } /** Insert an object into this variable at a position. */ @Override public void insertAt(Variable v, Variable index) throws ScriptException { if (v == null) throw new ScriptException(composeMessage("Can't insert a null object")); if (index == null) configurationNode.addChild(configurationNode.getChildCount(),v.getConfigurationNodeValue()); else { int indexValue = index.getIntValue(); if (indexValue < 0 || indexValue > configurationNode.getChildCount()) throw new ScriptException(composeMessage("Insert out of bounds: "+indexValue)); configurationNode.addChild(indexValue,v.getConfigurationNodeValue()); } } /** Delete an object from this variable at a position. */ @Override public void removeAt(Variable index) throws ScriptException { if (index == null) throw new ScriptException(composeMessage("Remove index cannot be null")); int indexValue = index.getIntValue(); if (indexValue < 0 || indexValue >= configurationNode.getChildCount()) throw new ScriptException(composeMessage("Remove index out of bounds: "+indexValue)); configurationNode.removeChild(indexValue); } @Override public VariableReference plus(Variable v) throws ScriptException { if (v == null) throw new ScriptException(composeMessage("Can't add a null object")); ConfigurationNode node = v.getConfigurationNodeValue(); ConfigurationNode cn = new ConfigurationNode(configurationNode.getType()); cn.setValue(configurationNode.getValue()); Iterator<String> attIter = configurationNode.getAttributes(); while (attIter.hasNext()) { String attrName = attIter.next(); String attrValue = configurationNode.getAttributeValue(attrName); cn.setAttribute(attrName,attrValue); } int i = 0; while (i < configurationNode.getChildCount()) { ConfigurationNode child = configurationNode.findChild(i++); cn.addChild(cn.getChildCount(),child); } cn.addChild(cn.getChildCount(),node); return new VariableConfigurationNode(cn); } /** Implement VariableReference to allow values to be set or cleared */ protected class ValueReference implements VariableReference { public ValueReference() { } @Override public void setReference(Variable v) throws ScriptException { if (v == null) configurationNode.setValue(null); else { String value = v.getStringValue(); configurationNode.setValue(value); } } @Override public Variable resolve() throws ScriptException { String value = configurationNode.getValue(); if (value == null) value = ""; return new VariableString(value); } @Override public boolean isNull() { return false; } } /** Implement VariableReference to allow attributes to be set or cleared */ protected class AttributeReference implements VariableReference { protected String attributeName; public AttributeReference(String attributeName) { this.attributeName = attributeName; } @Override public void setReference(Variable v) throws ScriptException { if (v == null) configurationNode.setAttribute(attributeName,null); else { String value = v.getStringValue(); configurationNode.setAttribute(attributeName,value); } } @Override public Variable resolve() throws ScriptException { String attrValue = configurationNode.getAttributeValue(attributeName); if (attrValue == null) throw new ScriptException(composeMessage("No attribute named '"+attributeName+"'")); return new VariableString(attrValue); } @Override public boolean isNull() { return (configurationNode.getAttributeValue(attributeName) == null); } } /** Extend VariableReference class so we capture attempts to set the reference, and actually overwrite the child when that is done */ protected class NodeReference implements VariableReference { protected int index; public NodeReference(int index) { this.index = index; } @Override public void setReference(Variable v) throws ScriptException { if (index < 0 || index >= configurationNode.getChildCount()) throw new ScriptException(composeMessage("Index out of range: "+index)); ConfigurationNode confNode = v.getConfigurationNodeValue(); configurationNode.removeChild(index); configurationNode.addChild(index,confNode); } @Override public Variable resolve() throws ScriptException { if (index < 0 || index >= configurationNode.getChildCount()) throw new ScriptException(composeMessage("Index out of range: "+index)); return new VariableConfigurationNode(configurationNode.findChild(index)); } /** Check if this reference is null */ @Override public boolean isNull() { return index < 0 || index >= configurationNode.getChildCount(); } } }