/****************************************************************************** * Copyright (c) 2008 g-Eclipse consortium * 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 * * Initial development of the original code was made for * project g-Eclipse founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributor(s): * Mariusz Wojtysiak - initial API and implementation * *****************************************************************************/ package eu.geclipse.jsdl.parametric.internal; import java.util.List; import javax.xml.xpath.XPathExpressionException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import eu.geclipse.jsdl.parametric.IGeneratedJsdl; import eu.geclipse.jsdl.parametric.IParametricJsdlHandler; import eu.geclipse.jsdl.parametric.ParametricJsdlException; import eu.geclipse.jsdl.xpath.XPathDocument; /** * This context replaces values in DOM Document containing jsdl and pass serialization to handler */ public class GenerationContext implements IGenerationContext, IGeneratedJsdl { private IParametricJsdlHandler handler; private Document currentJsdl; private String currentJsdlName; private XPathDocument xpath; /** * @param parametricJsdl * @param baseJsdl JSDL in which we will change parameter values * @param handler * @param xpathDocument */ GenerationContext( final Document baseJsdl, final IParametricJsdlHandler handler, final XPathDocument xpathDocument ) { this.handler = handler; this.currentJsdl = baseJsdl; this.xpath = xpathDocument; } @Override public IGenerationContext clone() { GenerationContext newContext = new GenerationContext( ( Document )this.currentJsdl.cloneNode( true ), this.handler, this.xpath ); return newContext; } /* (non-Javadoc) * @see eu.geclipse.jsdl.parametric.IGenerationContext#setValue(java.lang.String, javax.xml.xpath.XPathExpression, java.lang.String, org.eclipse.core.runtime.SubMonitor) */ public void setValue( final String xpathQuery, final String value ) throws ParametricJsdlException { try { NodeList nodeList = this.xpath.getNodes( this.currentJsdl, xpathQuery ); for( int index = 0; index < nodeList.getLength(); index++ ) { Node item = nodeList.item( index ); item.setTextContent( value ); } updateJsdlDescription( xpathQuery, value ); } catch( XPathExpressionException exception ){ throw new ParametricJsdlException( "Error occured during calling XPath query" ); //$NON-NLS-1$ } } public void storeGeneratedJsdl( final List<Integer> iterationsStack ) throws ParametricJsdlException { this.currentJsdlName = createIterationName( iterationsStack ); this.handler.newJsdlGenerated( this ); } private String createIterationName( final List<Integer> iterationsStack ) { StringBuilder builder = new StringBuilder(); for( Integer iteration : iterationsStack ) { builder.append( String.format( "[%03d]", iteration ) ); //$NON-NLS-1$ } return builder.toString(); } private void updateJsdlDescription( final String paramName, final String value ) throws XPathExpressionException { NodeList nodes = this.xpath.getNodes( this.currentJsdl.getDocumentElement(), "jsdl:JobDescription/jsdl:JobIdentification/jsdl:Description" ); //$NON-NLS-1$ Element description = null; if( nodes == null || nodes.getLength() == 0 ) { description = createXmlElement( this.currentJsdl.getDocumentElement(), "jsdl:JobDescription/jsdl:JobIdentification/jsdl:Description" ); //$NON-NLS-1$ } else { description = ( Element )nodes.item( 0 ); } description.setTextContent( getDescriptionString( description.getTextContent(), paramName, value ) ); } private String getDescriptionString( final String currentDescription, final String paramName, final String value ) { int begin = paramName.lastIndexOf( "/" ) + 1; //$NON-NLS-1$ String newEntry = String.format( "%s=%s", paramName.substring( begin ), value ); //$NON-NLS-1$ return currentDescription == null || currentDescription.length() == 0 ? newEntry : currentDescription + "\n" + newEntry; //$NON-NLS-1$ } public Document getDocument() { return this.currentJsdl; } public String getIterationName() { return this.currentJsdlName; } public String getParamValue( final String paramName ) throws ParametricJsdlException { try { return this.xpath.getValue( this.currentJsdl, paramName ); } catch( XPathExpressionException exception ) { throw new ParametricJsdlException( "Error occured during calling XPath query" ); //$NON-NLS-1$ } } private Element createXmlElement( final Element parent, final String pathString ) throws XPathExpressionException { Element element = parent; for( String currentNodeName : pathString.split( "/" ) ) { //$NON-NLS-1$ NodeList nodes = this.xpath.getNodes( element, "./" + currentNodeName ); //$NON-NLS-1$ if( nodes == null || nodes.getLength() == 0 ) { int namespaceIndex = currentNodeName.indexOf( ":" ); //$NON-NLS-1$ if( namespaceIndex > -1 && namespaceIndex + 1 < currentNodeName.length() ) { currentNodeName = currentNodeName.substring( namespaceIndex + 1 ); } Element newElement = this.currentJsdl.createElementNS( "http://schemas.ggf.org/jsdl/2005/11/jsdl", currentNodeName ); //$NON-NLS-1$ element.appendChild( newElement ); element = newElement; } else { element = ( Element )nodes.item( 0 ); } } return element; } public IParametricJsdlHandler getHandler() { return this.handler; } }