/**
Copyright (C) 2012 Delcyon, Inc.
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, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
*/
package com.delcyon.capo.controller.elements;
import java.util.logging.Level;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.delcyon.capo.controller.AbstractControl;
import com.delcyon.capo.controller.ControlElement;
import com.delcyon.capo.controller.ControlElementProvider;
import com.delcyon.capo.controller.Group;
import com.delcyon.capo.controller.server.ControllerClientRequestProcessor;
import com.delcyon.capo.server.CapoServer;
import com.delcyon.capo.xml.XPath;
import com.delcyon.capo.xml.XPathFunctionProcessor;
import com.delcyon.capo.xml.XPathFunctionProvider;
import com.delcyon.capo.xml.XPathFunctionUtility;
/**
* @author jeremiah
*
*/
@ControlElementProvider(name="group")
@XPathFunctionProvider
public class GroupElement extends AbstractControl implements XPathFunctionProcessor
{
public enum Attributes
{
type,
name,
value,
ref,
entry,
exec,
timeout,
exitCode,
eval,
stylesheet,
returns,
sessionId,
initialGroup,
table
}
private static final String[] functionNames = {"group","table","entry"};
private String groupName;
private Group group;
@SuppressWarnings("unchecked")
@Override
public Enum[] getAttributes()
{
return Attributes.values();
}
@SuppressWarnings("unchecked")
@Override
public Enum[] getRequiredAttributes()
{
return new Attributes[]{Attributes.name};
}
@Override
public String[] getSupportedNamespaces()
{
// TODO Auto-generated method stub
return null;
}
public Group getGroup()
{
return group;
}
@Override
public void init(Element controlElementDeclaration, ControlElement parentControlElement, Group parentGroup,ControllerClientRequestProcessor controllerClientRequestProcessor) throws Exception
{
super.init(controlElementDeclaration, parentControlElement, parentGroup, controllerClientRequestProcessor);
this.groupName = controlElementDeclaration.getAttribute(Attributes.name.toString());
this.group = new Group(groupName,parentGroup,this,controllerClientRequestProcessor);
//groupElement.getGroup().replaceVarsInAttributeValues(localElement);
this.group.setVars(controlElementDeclaration);
CapoServer.logger.log(Level.FINE, "init group = "+groupName);
//proccess entry attribute
if(getAttributeValue(Attributes.entry) != null && getAttributeValue(Attributes.entry).isEmpty() == false)
{
CapoServer.logger.log(Level.FINE, "Found Entry for "+getAttributeValue(Attributes.name));
Element contextElement = null;
if (getAttributeValue(Attributes.table).isEmpty() == false)
{
String tablePath = group.processVars(getAttributeValue(Attributes.table));
contextElement = (Element) XPath.selectSingleNode(controlElementDeclaration, getAttributeValue(Attributes.table));
if(contextElement == null)
{
throw new Exception("No table found at: "+tablePath);
}
}
else
{
contextElement = controlElementDeclaration;
}
Node entryNode = XPath.selectSingleNode(contextElement, group.processVars(getAttributeValue(Attributes.entry)),controlElementDeclaration.getPrefix());
if (entryNode != null)
{
group.set("entry."+entryNode.getLocalName(), XPath.getXPath(entryNode));
//add defaults from parent node, but only if the child has a parent that isn't this node.
if (entryNode.getParentNode().equals(controlElementDeclaration) == false)
{
NamedNodeMap defaultAttributeNodeList = entryNode.getParentNode().getAttributes();
for (int currentNode = 0; currentNode < defaultAttributeNodeList.getLength(); currentNode++)
{
Node attribute = defaultAttributeNodeList.item(currentNode);
group.set(attribute.getNodeName(), group.processVars(attribute.getNodeValue()));
}
}
//process attributes on actaul entry node
NamedNodeMap attributeNodeList = entryNode.getAttributes();
for (int currentNode = 0; currentNode < attributeNodeList.getLength(); currentNode++)
{
Node attribute = attributeNodeList.item(currentNode);
group.set(attribute.getNodeName(), group.processVars(attribute.getNodeValue()));
}
}
else
{
CapoServer.logger.log(Level.WARNING, "no entry found for "+group.processVars(controlElementDeclaration.getAttribute(Attributes.entry.toString()))+" in "+XPath.getXPath(contextElement));
}
}
}
@Override
public Object processServerSideElement() throws Exception
{
//process the children of this group
String initialGroupName = getAttributeValue(Attributes.initialGroup);
if (initialGroupName != null && initialGroupName.trim().isEmpty() == false)
{
processChildren(XPath.selectNodes(getControlElementDeclaration(), "./server:group[@"+Attributes.name+" = '"+initialGroupName+"']"), group, this, getControllerClientRequestProcessor());
}
else
{
processChildren(getControlElementDeclaration().getChildNodes(), group, this, getControllerClientRequestProcessor());
}
//then see if we have a returns attribute, and if so pull any matching vars from this group to the parent group
if (getControlElementDeclaration().hasAttribute(Attributes.returns.toString()) && getParentGroup() != null)
{
String[] varnnames = getControlElementDeclaration().getAttribute(Attributes.returns.toString()).split(",");
for (String varName : varnnames)
{
if (group.containsLocalKey(varName))
{
getParentGroup().set(varName, group.getLocalValue(varName));
}
}
}
return null;
}
@Override
public String[] getXPathFunctionNames()
{
return functionNames;
}
@Override
public Object processFunction(String functionName, Object... arguments) throws Exception
{
Node contextNode = getContextNode();
String prefix = XPathFunctionUtility.getPrefix(contextNode,arguments,1);
if (functionName.equals("group"))
{
return XPath.selectSingleNode(contextNode, "//"+prefix+"group[@name = '"+arguments[0]+"']");
}
else if (functionName.equals("table"))
{
return XPath.selectSingleNode(contextNode, "//"+prefix+"table[@name = '"+arguments[0]+"']");
}
else if (functionName.equals("entry"))
{
return XPath.selectSingleNode(contextNode, "//"+prefix+"table[@name = '"+arguments[0]+"']/*[@"+arguments[1]+" = //var[@name = '"+arguments[2]+"']/@value]");
}
else
{
return null;
}
}
@Override
public void destroy() throws Exception
{
super.destroy();
if (group != null)
{
group.destroy();
}
}
public void setGroup(Group group)
{
this.group = group;
}
}