All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.roboconf.dm.templating.internal.helpers.AllHelper Maven / Gradle / Ivy

/**
 * Copyright 2013-2016 Linagora, Université Joseph Fourier, Floralis
 *
 * The present code is developed in the scope of the joint LINAGORA -
 * Université Joseph Fourier - Floralis research program and is designated
 * as a "Result" pursuant to the terms and conditions of the LINAGORA
 * - Université Joseph Fourier - Floralis research program. Each copyright
 * holder of Results enumerated here above fully & independently holds complete
 * ownership of the complete Intellectual Property rights applicable to the whole
 * of said Results, and may freely exploit it in any manner which does not infringe
 * the moral rights of the other copyright holders.
 *
 * Licensed 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 net.roboconf.dm.templating.internal.helpers;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Logger;

import net.roboconf.core.utils.Utils;
import net.roboconf.dm.templating.internal.contexts.ApplicationContextBean;
import net.roboconf.dm.templating.internal.contexts.InstanceContextBean;

import org.apache.commons.lang3.StringUtils;

import com.github.jknack.handlebars.Context;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;

/**
 * Helper needed to select all the instances matching a given criterion.
 * @author Pierre Bourret - Université Joseph Fourier
 */
public class AllHelper implements Helper {

	public static final String NAME = "all";
	private final Logger logger = Logger.getLogger( getClass().getName());


	/**
	 * Selects instances according to a selection path.
	 * 

For example:

*
	 * {{#all children path="/VM/Apache" installer="script"}}
	 *   {{path}}
	 * {{/all}}
	 * 
*/ @Override public CharSequence apply( final Object computedContext, final Options options ) throws IOException { // Get parameters Object context = options.context.model(); String componentPath = null; if( computedContext instanceof String ) componentPath = (String) computedContext; if( Utils.isEmptyOrWhitespaces( componentPath )) componentPath = InstanceFilter.JOKER; // Process them CharSequence result = StringUtils.EMPTY; if (context instanceof ApplicationContextBean) { // Implicit: all instances of the application. result = safeApply(((ApplicationContextBean) context).getInstances(), options, componentPath ); } else if (context instanceof InstanceContextBean) { // Implicit: all descendants of the instance. result = safeApply( descendantInstances((InstanceContextBean) context), options, componentPath ); } else { this.logger.warning( "An unexpected context was received: " + (context == null ? null : context.getClass())); } return result; } /** * Same as above, but with type-safe arguments. * * @param instances the instances to which this helper is applied. * @param options the options of this helper invocation. * @return a string result. * @throws IOException if a template cannot be loaded. */ private String safeApply( Collection instances, Options options, String componentPath ) throws IOException { // Parse the filter. String installerName = (String) options.hash.get( "installer" ); final InstanceFilter filter = InstanceFilter.createFilter( componentPath, installerName ); // Apply the filter. final Collection selectedInstances = filter.apply( instances ); // Apply the content template of the helper to each selected instance. final StringBuilder buffer = new StringBuilder(); final Context parent = options.context; int index = 0; final int last = selectedInstances.size() - 1; for( final InstanceContextBean instance : selectedInstances ) { final Context current = Context.newBuilder( parent, instance ) .combine( "@index", index ) .combine( "@first", index == 0 ? "first" : "" ) .combine( "@last", index == last ? "last" : "" ) .combine( "@odd", index % 2 == 0 ? "" : "odd" ) .combine( "@even", index % 2 == 0 ? "even" : "" ) .build(); index++; buffer.append( options.fn( current )); } return buffer.toString(); } /** * Returns all the descendant instances of the given instance. * @param instance the instance which descendants must be retrieved. * @return the descendants of the given instance. */ private static Collection descendantInstances( final InstanceContextBean instance ) { final Collection result = new ArrayList(); for (final InstanceContextBean child : instance.getChildren()) { result.add( child ); result.addAll( descendantInstances( child ) ); } return result; } }