/******************************************************************************* * Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved * * 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 org.cloudifysource.dsl.entry; import groovy.lang.Closure; import groovy.lang.GString; import java.io.File; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.cloudifysource.domain.ExecutableEntriesMap; import org.cloudifysource.domain.entry.ExecutableDSLEntry; import org.cloudifysource.dsl.internal.DSLValidationException; /*********** * Factory class for creating an executable DSL entry from a DSL value. * * @author barakme * @since 2.2.0 * */ public final class ExecutableDSLEntryFactory { // private static GroovyFileValidater groovyValidater = new GroovyFileValidater(); private ExecutableDSLEntryFactory() { // private constructor to prevent instantiation } /************ * Creates a map of executable entries, keyed by the name of the entry. Useful for custom commands, though it may * come in handy elsewhere. * * @param arg * the input value. * @param entryName * the entry name. * @param workDirectory * the work directory for this entry. * @return the executable entries map. * @throws DSLValidationException * if an entry is invalid. */ public static ExecutableEntriesMap createEntriesMap(final Object arg, final Object entryName, final File workDirectory) throws DSLValidationException { final ExecutableEntriesMap result = new ExecutableEntriesMap(); copyElementsToEntriesMap(arg, entryName, result, workDirectory); return result; } // TODO - re-enable this to activate groovy file validations // private static void // validateStringEntry(final StringExecutableEntry stringExecutableEntry, final File workDirectory) { // final String command = stringExecutableEntry.getCommand(); // final String[] parts = command.split(" "); // final String fileName = parts[0]; // if (fileName.endsWith(".groovy")) { // File file = new File(fileName); // if (!file.isAbsolute()) { // file = new File(workDirectory, fileName); // } // // // if (file.exists() && file.isFile()) { // // GroovyFileCompilationResult result = groovyValidater.validateFile(file); // // if (!result.isSuccess()) { // // throw new DSLValidationException(result.getErrorMessage(), result.getCause()); // // } // // } // } // // } /**************** * Created an executable entry from a DSL value. The argument must be from one of the supported types. * * @param arg * the dsl value. * @param entryName * the dsl entry name. * @param workDirectory * The directory where the DSL is being processed. * @return the executable entry wrapper for the given arg. * @throws DSLValidationException * if the entry is invalid. */ @SuppressWarnings("unchecked") public static ExecutableDSLEntry createEntry(final Object arg, final Object entryName, final File workDirectory) throws DSLValidationException { if (arg == null) { // this might be useful in service extension, where the child service wants to remove a command added by the // parent service return null; } if (arg instanceof Closure<?>) { return new ClosureExecutableEntry((Closure<?>) arg); } if (arg instanceof String) { final StringExecutableEntry stringExecutableEntry = new StringExecutableEntry((String) arg); //validateStringEntry(stringExecutableEntry, workDirectory); return stringExecutableEntry; } else if (arg instanceof GString) { return new StringExecutableEntry(arg.toString()); } else if (arg instanceof List<?>) { return new ListExecutableEntry((List<String>) arg); } else if (arg instanceof Map<?, ?>) { // verify types of keys and objects, and create a new map with wrapper entry objects for each value. final MapExecutableEntry result = new MapExecutableEntry(); copyElementsToEntriesMap(arg, entryName, result, workDirectory); return result; } throw new IllegalArgumentException("The entry: " + entryName + " is not a valid executable entry: The given value: " + arg + " is of type: " + arg.getClass().getName() + " which is not a valid type for an executable entry"); } private static void copyElementsToEntriesMap(final Object arg, final Object entryName, final Map<String, ExecutableDSLEntry> result, final File workDirectory) throws DSLValidationException { @SuppressWarnings("unchecked") final Map<Object, Object> originalMap = (Map<Object, Object>) arg; final Set<Entry<Object, Object>> entries = originalMap.entrySet(); for (final Entry<Object, Object> entry : entries) { Object key = entry.getKey(); if (!(key instanceof String)) { throw new IllegalArgumentException("Entry " + entryName + " has a sub entry key which is not a string. Subentry was: " + key); } // RECURSIVE CALL! final ExecutableDSLEntry executableEntry = createEntry(entry.getValue(), key, workDirectory); result.put((String) key, executableEntry); } } }