/** * This file is part of CloudML [ http://cloudml.org ] * * Copyright (C) 2012 - SINTEF ICT * Contact: Franck Chauvel <franck.chauvel@sintef.no> * * Module: root * * CloudML is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * CloudML 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with CloudML. If not, see * <http://www.gnu.org/licenses/>. */ /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.cloudml.connectors.util; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.cloudml.connectors.ConnectorFactory; import org.cloudml.core.Component; import org.cloudml.core.ComponentInstance; import org.cloudml.core.ExternalComponent; import org.cloudml.core.ExternalComponentInstance; import org.cloudml.core.Property; import org.cloudml.core.RelationshipInstance; import org.cloudml.core.Resource; /** * This configuration agent works on war files * * It takes a target "WAR" component, a source component that contains the * required configuration value (such as a standalone database), and a resource * that contains the configuration pairs (usually carried by a {@link Relationship). * * The properties carried by the configuration resource are in the following format: * * 1. path_{name} -> {entry}::{xpath} : config the given xml element by {xpath} inside * the entry {entry}, the value with be specified in value_{name} with the same name * 2. value_{name} -> string_with_embedded queries: where the queries obtain the * values from the any cloudml elements that are reachable from the resource or * the relationship instance (usually from the component instance * e.g., "jdbc:mysql://@instance{providedEnd/owner/value/publicAddress}" * * @author Hui Song */ public class WarXmlConfigValet extends ConfigValet { private ComponentInstance warCompInst; private Resource configResource; private RelationshipInstance relationshipInstance; public WarXmlConfigValet(RelationshipInstance relationshipInstance, Resource configResource){ this.relationshipInstance = relationshipInstance; this.warCompInst = relationshipInstance.getRequiredEnd().getOwner().get(); this.configResource = configResource; } @Override public void config() { ComponentInstance warCompi = this.warCompInst; Component warComp = warCompi.getType(); ZipModifier zipModifier = new ZipModifier( warComp.getProperties().valueOf("warfile"), warComp.getProperties().valueOf("temp-warfile") ); Map<String,Map<String, String>> entryKv = new HashMap<String,Map<String,String>>(); for(Property prop : configResource.getProperties()){ String name = prop.getName(); if("valet".equals(name) || "path".equals(name)) // they are preserved keywords continue; if(name.startsWith("path")){ String entry_path_value = CloudMLQueryUtil.cloudmlStringRecover( prop.getValue(), configResource, relationshipInstance ); String[] entry_path = entry_path_value.split("::"); if(!entryKv.containsKey(entry_path[0])) entryKv.put(entry_path[0], new HashMap<String,String>()); Map<String,String> kv = entryKv.get(entry_path[0]); String value_value = configResource.getProperties() .valueOf(name.replaceFirst("path","value")); String value = CloudMLQueryUtil.cloudmlStringRecover( value_value, configResource, relationshipInstance ); if(value != null){ kv.put(entry_path[1], value); } } } try{ zipModifier.updateXMLElement(entryKv); }catch(Exception ex){ ex.printStackTrace(); throw new RuntimeException("Error in writing XML configurations in the WAR file", ex); } } }