/**********************************************************************
 * Copyright (c) 2008 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM - Initial API and implementation
 *
 * $Id: QueryBuidlerServiceMetatData.java,v 1.18 2008/08/14 03:37:30 sleeloy Exp $
 **********************************************************************/

package org.eclipse.cosmos.internal.dr.drs.service.outputter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.cosmos.dc.provisional.cmdbf.query.client.QueryServiceClient;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.QueryMetadataTransformer;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.input.artifacts.IDialect;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.input.artifacts.IQueryCapabilities;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.input.artifacts.IQueryServiceMetadata;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.input.artifacts.IRecordType;
import org.eclipse.cosmos.dc.provisional.cmdbf.services.metadata.transform.input.artifacts.IRecordTypes;
import org.eclipse.cosmos.internal.dr.drs.service.handler.common.MapParameterImpl;
import org.eclipse.cosmos.internal.dr.drs.service.handler.common.SessionResolveFixedTreeIDs;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.AbstractOutputter;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IParameters;
import org.w3c.dom.Element;


public class QueryBuidlerServiceMetatData extends AbstractOutputter {
	public static final String MDREPR="epr"; //$NON-NLS-1$
	public static final String USERNAME="username"; //$NON-NLS-1$
	public static final String PASSWORD="password"; //$NON-NLS-1$
	public static final String SOAPVERSION="soapversion"; //$NON-NLS-1$
	
	protected String rootId;

	/* (non-Javadoc)
	 * @see org.eclipse.cosmos.dr.drs.service.handler.sml.IOutputter#render(java.io.PrintWriter, java.util.Map)
	 */
	public void render(PrintWriter output, IParameters input) throws Exception {
		String mdrEPR = input.getParameter(MDREPR);
		String username = input.getParameter(USERNAME);
		String password = input.getParameter(PASSWORD);
		String soapversion = input.getParameter(SOAPVERSION);		

		if ((mdrEPR != null)){
			
			//get cdmbf query
			IQueryServiceMetadata serviceMetatData = getServiceMetatData(mdrEPR, username, password, soapversion);
			//transfrom service meta data to json					
			renderServiceMetaData(output, serviceMetatData);
				
		}
	}

	protected IQueryServiceMetadata getServiceMetatData(String mdrEPR, String username, String password, String soapversion) throws Exception{
		QueryServiceClient queryService =   new QueryServiceClient(mdrEPR);
		if (username != null)
			queryService.setUsername(username);
		if (password != null)
			queryService.setPassword(password);
		if (soapversion != null)
			queryService.setSoapVersion(Integer.parseInt(soapversion));
		Element result = queryService.getQueryServiceMetadata();
		if (result==null) return null; 

		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		trans.transform(new DOMSource(result), new StreamResult(bout));
		InputStream is = new ByteArrayInputStream(bout.toByteArray());
		
		
		IQueryServiceMetadata queryServiceMetadata = QueryMetadataTransformer.transform(is);
            
	    return queryServiceMetadata;
	}
	
	protected void renderServiceMetaData(PrintWriter pw,
			IQueryServiceMetadata serviceMetatData) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// Read the entire document into memory

		boolean serviceMetaDataSupport = false;
		boolean relationshipSupport = false;
		boolean relationshipDepthLimitSupport = false;
		boolean relationshipMinMaxSupport = false;
		boolean contentSelectorSupport = false;
		boolean csRecordTypeSelector = false;
		boolean csPropertySelector = false;
		boolean xPathSupport = false;
		boolean recordConstraintSuport = false;
		boolean rcsRecordTypeConstraintSupport = false;
		boolean rcsPropertyConstraintSupport = false;
		boolean propertyValuesOpSuport = false;
		List<String> operators = new ArrayList<String>();
		List<String> xDialect = new ArrayList<String>();
		List<String> namespace = new ArrayList<String>();
		List<String> recordTypes = new ArrayList<String>();

		if ((serviceMetatData != null) && (serviceMetatData.getQueryCapabilities() != null)) { 
			IQueryCapabilities queryCapabilities = serviceMetatData
					.getQueryCapabilities();
			// get children nodes
			if (queryCapabilities.getRelationshipTemplateSupport() != null) {
				relationshipSupport = true;
				relationshipDepthLimitSupport = queryCapabilities
						.getRelationshipTemplateSupport().isDepthLimit();
				relationshipMinMaxSupport = queryCapabilities
						.getRelationshipTemplateSupport().isMinimumMaximum();
			} if (queryCapabilities.getContentSelectorSupport() != null) { 
				contentSelectorSupport = true;
				csRecordTypeSelector = queryCapabilities
						.getContentSelectorSupport().isRecordTypeSelector();
				csPropertySelector = queryCapabilities
						.getContentSelectorSupport().isPropertySelector();
			} if (queryCapabilities.getRecordConstraintSupport() != null) { 
				recordConstraintSuport = true;
				rcsRecordTypeConstraintSupport = queryCapabilities.getRecordConstraintSupport().isRecordTypeConstraint();
				rcsPropertyConstraintSupport = queryCapabilities.getRecordConstraintSupport().isPropertyValueConstraint();

				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isEqual())
					operators.add("="); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isLessOrEqual())
					operators.add("<="); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isLess())
					operators.add("<"); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isGreater())
					operators.add(">"); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isGreaterOrEqual())
					operators.add(">="); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isContains())
					operators.add("contains"); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isLike())
					operators.add("like"); //$NON-NLS-1$
				if (queryCapabilities.getRecordConstraintSupport().getPropertyValueOperators().isNull())
					operators.add("isNull"); //$NON-NLS-1$
				propertyValuesOpSuport = (operators.size() > 0);
			} if (queryCapabilities.getXpathSupport() != null) { //$NON-NLS-1$
				xPathSupport = true;
				IDialect[] dialectList = queryCapabilities.getXpathSupport()
						.getDialects();
				for (int z = 0; z < dialectList.length; z++) {
					IDialect dialectNode = dialectList[z];
					xDialect.add(dialectNode.getDialect());
				}
			}
			if (serviceMetatData.getRecordTypeList() != null){
				IRecordTypes[] types = serviceMetatData.getRecordTypeList().getRecordTypes();
				for (int x = 0; x < types.length; x++){
					namespace.add(types[x].getNamespace());
					IRecordType[] recordTypeList = types[x].getRecordType();
					for (int y = 0; y < recordTypeList.length; y++){
						recordTypes.add(recordTypeList[y].getLocalName());
					}
				}
			}

		}

		serviceMetaDataSupport = (relationshipSupport
				|| relationshipDepthLimitSupport || relationshipMinMaxSupport
				|| contentSelectorSupport || csRecordTypeSelector
				|| csPropertySelector || xPathSupport || recordConstraintSuport
				|| rcsRecordTypeConstraintSupport
				|| rcsPropertyConstraintSupport || propertyValuesOpSuport);

		if (serviceMetaDataSupport) {
			StringBuffer buffer = new StringBuffer(	"{ identifier: \"nodeClass\",  label: \"title\",  items:["); //$NON-NLS-1$

			List<String> children = new ArrayList<String>();
			generateRules(
					false,
					children,
					"", relationshipSupport, relationshipDepthLimitSupport, relationshipMinMaxSupport, contentSelectorSupport, csRecordTypeSelector, csPropertySelector, xPathSupport, recordConstraintSuport, rcsRecordTypeConstraintSupport, rcsPropertyConstraintSupport, propertyValuesOpSuport); //$NON-NLS-1$
			if (relationshipSupport) {
				generateRules(
						true,
						children,
						"rel", relationshipSupport, relationshipDepthLimitSupport, relationshipMinMaxSupport, contentSelectorSupport, csRecordTypeSelector, csPropertySelector, xPathSupport, recordConstraintSuport, rcsRecordTypeConstraintSupport, rcsPropertyConstraintSupport, propertyValuesOpSuport); //$NON-NLS-1$
			}
			for (int x = 0; x < children.size(); x++) {
				if (x != 0)
					buffer.append("\n,"); //$NON-NLS-1$
				buffer.append(children.get(x));
			}

			buffer.append("]}"); //$NON-NLS-1$
	
			StringBuffer nodeBuffer = new StringBuffer(
					"{ identifier: \"nodeClass\",  label: \"title\",  items:["); //$NON-NLS-1$
			List<String> nodes = new ArrayList<String>();
			generateNodes(
					false,
					nodes,
					"", relationshipSupport, relationshipDepthLimitSupport, relationshipMinMaxSupport, contentSelectorSupport, csRecordTypeSelector, csPropertySelector, xPathSupport, recordConstraintSuport, rcsRecordTypeConstraintSupport, rcsPropertyConstraintSupport, propertyValuesOpSuport, xDialect, operators,namespace,recordTypes); //$NON-NLS-1$
			for (int x = 0; x < nodes.size(); x++) {
				if (x != 0)
					nodeBuffer.append("\n,"); //$NON-NLS-1$
				nodeBuffer.append(nodes.get(x));
			}
			nodeBuffer.append("]}"); //$NON-NLS-1$
	
			StringBuffer parentBuffer = new StringBuffer("{"); //$NON-NLS-1$
			parentBuffer.append("menuRules:") //$NON-NLS-1$
					.append(buffer)
					.append(",factory:") //$NON-NLS-1$
					.append(nodeBuffer)
					.append(",supportRel:") //$NON-NLS-1$
					.append(relationshipSupport)
					.append("}"); //$NON-NLS-1$
	
			pw.println(parentBuffer.toString());
		}
		else{
			pw.println("{capabilityUnknown: true}"); //$NON-NLS-1$
		}

	}
	
	protected void generateNodes(boolean isRel, List<String>children, String prefix, boolean relationshipSupport, boolean  relationshipDepthLimitSupport, boolean relationshipMinMaxSupport, boolean  contentSelectorSupport, boolean  csRecordTypeSelector, boolean  csPropertySelector, boolean  xPathSupport, boolean  recordConstraintSuport, boolean  rcsRecordTypeConstraintSupport, boolean  rcsPropertyConstraintSupport, boolean  propertyValuesOpSuport, List<String> xDialect, List<String> opList, List<String> namespace, List<String> recordTypes){
		String namespaceString = ""; //$NON-NLS-1$
		for (int x = 0; x < namespace.size(); x++){
			if (x != 0)
				namespaceString +=","; //$NON-NLS-1$
			namespaceString += "'"+namespace.get(x)+"'"; //$NON-NLS-1$ //$NON-NLS-2$
		}				
		String recordTypesString = ""; //$NON-NLS-1$
		for (int x = 0; x < recordTypes.size(); x++){
			if (x != 0)
				recordTypesString +=","; //$NON-NLS-1$
			recordTypesString += "'"+recordTypes.get(x)+"'"; //$NON-NLS-1$ //$NON-NLS-2$
		}
		 children.add("{nodeLbl:'itemTemplate',nodeClass:'itemTemplate',factoryType:'dojox.grid.data.Table',factory: [[ 'id', ''],[ 'suppressFromResult', false]]}"); //$NON-NLS-1$
		 children.add("{nodeLbl:'any',nodeClass:'any',factoryType:'dojo.data.ItemFileWriteStore'}"); //$NON-NLS-1$
		 children.add("{nodeLbl:'instanceIdConstraint',nodeClass:'instanceIdConstraint',addChild:['instanceId']}"); //$NON-NLS-1$
		 children.add("{nodeLbl:'instanceId',nodeClass:'instanceId',factoryType:'dojox.grid.data.Table',pop:true,factory: [[ 'mdrId', ''],[ 'localId', '']]}");
		 if (relationshipSupport){
			 children.add("{nodeLbl:'relationshipTemplate',nodeClass:'relationshipTemplate',factoryType:'dojox.grid.data.Table',factory: [[ 'id', ''],[ 'suppressFromResult', false]]}"); //$NON-NLS-1$
			 children.add("{nodeLbl:'any',nodeClass:'relany',factoryType:'dojo.data.ItemFileWriteStore'}"); //$NON-NLS-1$
			 children.add("{nodeLbl:'instanceId',nodeClass:'relinstanceId',factoryType:'dojox.grid.data.Table',pop:true,factory: [[ 'mdrId', ''],[ 'localId', '']]}");
			 children.add("{nodeLbl:'instanceIdConstraint',nodeClass:'relinstanceIdConstraint',addChild:['relinstanceId']}"); //$NON-NLS-1$
			 children.add("{nodeLbl:'sourceTemplate',nodeClass:'sourceTemplate',factoryType:'dojox.grid.data.Table',factory: [[ 'ref', '']"+((relationshipMinMaxSupport)?",[ 'minimum', ''],[ 'maximum', '']":"")+"]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			 children.add("{nodeLbl:'targetTemplate',nodeClass:'targetTemplate',factoryType:'dojox.grid.data.Table',factory: [[ 'ref', '']"+((relationshipMinMaxSupport)?",[ 'minimum', ''],[ 'maximum', '']":"")+"]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			 if (relationshipDepthLimitSupport)
				 children.add("{nodeLbl:'depthLimit',nodeClass:'depthLimit',factoryType:'dojox.grid.data.Table',factory: [[ 'maxIntermediateItems', '0'],[ 'intermediateItemTemplate', '']]}"); //$NON-NLS-1$
			 
		 }

		 if (contentSelectorSupport){
			 children.add("{nodeLbl:'contentSelector',nodeClass:'contentSelector',factoryType:'dojox.grid.data.Table',factory: [[ 'matchedRecords', true]]}"); //$NON-NLS-1$
			 if (relationshipSupport)
				 children.add("{nodeLbl:'contentSelector',nodeClass:'relcontentSelector',factoryType:'dojox.grid.data.Table',factory: [[ 'matchedRecords', true]]}"); //$NON-NLS-1$
			if (csRecordTypeSelector){
				
				 children.add("{nodeLbl:'selectedRecordType',nodeClass:'selectedRecordType',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				 if (relationshipSupport)
					 children.add("{nodeLbl:'selectedRecordType',nodeClass:'relselectedRecordType',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				if (csPropertySelector){
					 children.add("{nodeLbl:'selectedProperty',nodeClass:'selectedProperty',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					 if (relationshipSupport)
						 children.add("{nodeLbl:'selectedProperty',nodeClass:'relselectedProperty',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
			}
			 
		 }
			if (recordConstraintSuport){
				 children.add("{nodeLbl:'recordConstraint',nodeClass:'recordConstraint'}"); //$NON-NLS-1$
				 if (relationshipSupport)
					 children.add("{nodeLbl:'recordConstraint',nodeClass:'relrecordConstraint'}"); //$NON-NLS-1$
				if (rcsRecordTypeConstraintSupport){
					 children.add("{nodeLbl:'recordType',nodeClass:'recordType',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					 if (relationshipSupport)
						 children.add("{nodeLbl:'recordType',nodeClass:'relrecordType',factoryType:'dojox.grid.data.Table',factory: [[ 'namespace', ''],[ 'localName', '']], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				if (rcsPropertyConstraintSupport){
					String opString = ""; //$NON-NLS-1$
					for (int x = 0; x < opList.size(); x++){
						if (x != 0)
							opString +=","; //$NON-NLS-1$
						opString += "'"+opList.get(x)+"'"; //$NON-NLS-1$ //$NON-NLS-2$
					}
					 children.add("{nodeLbl:'propertyValue',nodeClass:'propertyValue',factoryType:'org.eclipse.cosmos.provisional.dr.ps.components.widget.PropValueDataStore', params:[[{datao:[[ 'namespace', ''],[ 'localName', '' ]], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]],opOptions:[["+opString+"]]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
					 
					 if (relationshipSupport)
						 children.add("{nodeLbl:'propertyValue',nodeClass:'relpropertyValue',factoryType:'org.eclipse.cosmos.provisional.dr.ps.components.widget.PropValueDataStore', params:[[{datao:[[ 'namespace', ''],[ 'localName', '' ]], metadata:[[{type:'Select', options:["+namespaceString+"]},{type:'Select', options:["+recordTypesString+"]}]],opOptions:[["+opString+"]]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
				}					 		 				 				 			 					
			}
			if (xPathSupport){
				String dialectString = ""; //$NON-NLS-1$
				for (int x = 0; x < xDialect.size(); x++){
					if (x != 0)
						dialectString +=","; //$NON-NLS-1$
					dialectString += "'"+xDialect.get(x)+"'"; //$NON-NLS-1$ //$NON-NLS-2$
				}
				
				 children.add("{nodeLbl:'expression',nodeClass:'expression',factoryType:'dojo.data.ItemFileWriteStore'}"); //$NON-NLS-1$
				 children.add("{nodeLbl:'prefixMapping',nodeClass:'prefixMapping',factoryType:'dojox.grid.data.Table',factory: [[ 'prefix', ''],[ 'namespace', '']]}"); //$NON-NLS-1$
				 children.add("{nodeLbl:'xpathExpression',nodeClass:'xpathExpression',addChild:['expression'],factoryType:'dojox.grid.data.Table',factory: [[ 'dialect', '']], metadata:[[{type:'Select', options:["+dialectString+"]}]]}"); //$NON-NLS-1$ //$NON-NLS-2$
				 if (relationshipSupport){
					 children.add("{nodeLbl:'expression',nodeClass:'relexpression',factoryType:'dojo.data.ItemFileWriteStore'}"); //$NON-NLS-1$
					 children.add("{nodeLbl:'prefixMapping',nodeClass:'relprefixMapping',factoryType:'dojox.grid.data.Table',factory: [[ 'prefix', ''],[ 'namespace', '']]}"); //$NON-NLS-1$
					 children.add("{nodeLbl:'xpathExpression',nodeClass:'relxpathExpression',addChild:['relexpression'],factoryType:'dojox.grid.data.Table',factory: [[ 'dialect', '']], metadata:[[{type:'Select', options:["+dialectString+"]}]]}");					  //$NON-NLS-1$ //$NON-NLS-2$
				 }
			
			}
		 
	}
	
		
	protected void generateRules(boolean isRel, List<String>children, String prefix, boolean relationshipSupport, boolean  relationshipDepthLimitSupport, boolean relationshipMinMaxSupport, boolean  contentSelectorSupport, boolean  csRecordTypeSelector, boolean  csPropertySelector, boolean  xPathSupport, boolean  recordConstraintSuport, boolean  rcsRecordTypeConstraintSupport, boolean  rcsPropertyConstraintSupport, boolean  propertyValuesOpSuport){
		String contentRefSelectStr = ""; //$NON-NLS-1$
		String recordConstraint = ""; //$NON-NLS-1$
		String xpathExpressionStr = ""; //$NON-NLS-1$
		if (contentSelectorSupport){
			contentRefSelectStr = "{_reference:'"+prefix+"contentSelector'},"; //$NON-NLS-1$ //$NON-NLS-2$
			String csRecordTypeElem = ""; //$NON-NLS-1$
			if (csRecordTypeSelector){
				csRecordTypeElem= ",children:[{_reference:'"+prefix+"selectedRecordType'}"; //$NON-NLS-1$ //$NON-NLS-2$
				String csPropertyTypeElem = ""; //$NON-NLS-1$
				if (csPropertySelector){
					csPropertyTypeElem= ",children:[{_reference:'"+prefix+"selectedProperty'}"; //$NON-NLS-1$ //$NON-NLS-2$
					children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" selectedProperty',nodeClass:'"+prefix+"selectedProperty',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
				}
				children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" selectedRecordType',nodeClass:'"+prefix+"selectedRecordType'"+csPropertyTypeElem+",{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
			}
			children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" contentSelector',nodeClass:'"+prefix+"contentSelector', menuRules:['"+prefix+"contentSelector','"+prefix+"xpathExpression'] "+csRecordTypeElem+",{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$

		}
		if (recordConstraintSuport){
			recordConstraint="{_reference:'"+prefix+"recordConstraint'},"; //$NON-NLS-1$ //$NON-NLS-2$
			String rcsRecordType = ""; //$NON-NLS-1$
			if (rcsRecordTypeConstraintSupport){
				rcsRecordType= "{_reference:'"+prefix+"recordType'},"; //$NON-NLS-1$ //$NON-NLS-2$
				children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" recordType',nodeClass:'"+prefix+"recordType',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			}
			String rcsPropertyValue = ""; //$NON-NLS-1$
			if (rcsPropertyConstraintSupport){
				rcsPropertyValue= "{_reference:'"+prefix+"propertyValue'},"; //$NON-NLS-1$ //$NON-NLS-2$
				children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" propertyValue',nodeClass:'"+prefix+"propertyValue',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			}					 		 				 				 			 					
			children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" recordConstraint',nodeClass:'"+prefix+"recordConstraint',menuRules:['"+prefix+"xpathExpression'],children:["+rcsRecordType+rcsPropertyValue+"{_reference:'"+prefix+"any'},{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
		}
		if (xPathSupport){
			 xpathExpressionStr = "{_reference:'"+prefix+"xpathExpression'},"; //$NON-NLS-1$ //$NON-NLS-2$
			 children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" expression',nodeClass:'"+prefix+"expression',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			 children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" prefixMapping',nodeClass:'"+prefix+"prefixMapping',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			 children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" xpathExpression',nodeClass:'"+prefix+"xpathExpression',menuRules:['"+prefix+"instanceIdConstraint','"+prefix+"contentSelector','"+prefix+"recordConstraint'],children:[{_reference:'"+prefix+"prefixMapping'},{_reference:'"+prefix+"expression'},{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
		}
		children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" instanceIdContraint',nodeClass:'"+prefix+"instanceIdConstraint',menuRules:['"+prefix+"instanceIdConstraint','"+prefix+"xpathExpression'],children:[{_reference:'"+prefix+"instanceId'},{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
		children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" instanceId',nodeClass:'"+prefix+"instanceId',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" any',nodeClass:'"+prefix+"any',children:[{_reference:'"+prefix+"delete'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		children.add("{title:'delete',nodeClass:'"+prefix+"delete'}"); //$NON-NLS-1$ //$NON-NLS-2$
		if (isRel){
			if (relationshipSupport){
				String depthLimit = ""; //$NON-NLS-1$
				if (relationshipDepthLimitSupport){
					depthLimit="{_reference:'depthLimit'},"; //$NON-NLS-1$
					children.add("{title:'"+Messages.getString("QueryBuidlerServiceMetatData.48")+" depthLimit',nodeClass:'depthLimit',menuRules:['depthLimit']}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				children.add("{title:'',nodeClass:'relationshipTemplate',children:["+contentRefSelectStr+recordConstraint+xpathExpressionStr+depthLimit+"{_reference:'"+prefix+"instanceIdConstraint'},{_reference:'"+prefix+"any'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}
		}
		else
			children.add("{title:'',nodeClass:'"+prefix+"itemTemplate',children:["+contentRefSelectStr+recordConstraint+xpathExpressionStr+"{_reference:'"+prefix+"instanceIdConstraint'},{_reference:'"+prefix+"any'}]}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		
	}
	protected boolean extractXSResult(Element elem, String attribute){
		return  (("true" == elem.getAttribute(attribute)) || ("1" == elem.getAttribute(attribute)));			 //$NON-NLS-1$ //$NON-NLS-2$
	}

	
	public static final void main(String argv[]) throws Exception{
		QueryBuidlerServiceMetatData out = new QueryBuidlerServiceMetatData();
		out.setIdResolver(new SessionResolveFixedTreeIDs());
		Map input = new HashMap();
		input.put("epr", "tests"); //$NON-NLS-1$ //$NON-NLS-2$
		IParameters param = new MapParameterImpl(input);
		PrintWriter ps = new PrintWriter(System.out);
		out.render(ps, param);
		ps.flush();
		
	}

}
