package com.sixsq.slipstream.persistence; /* * +=================================================================+ * SlipStream Server (WAR) * ===== * Copyright (C) 2013 SixSq Sarl (sixsq.com) * ===== * 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. * -=================================================================- */ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import javax.persistence.CascadeType; import javax.persistence.FetchType; import javax.persistence.MapKey; import javax.persistence.MappedSuperclass; import javax.persistence.OneToMany; import org.hibernate.annotations.CollectionType; //import org.hibernate.annotations.Type; import org.simpleframework.xml.ElementMap; import com.sixsq.slipstream.exceptions.ValidationException; // The mapping between a parameterized class and its associated // parameter type must be given here. // // Type S = the subclass of Parameterized and // Type T = the corresponding subclass of Parameter // // For example, use <User, UserParameter> for the user parameter // mapping. // @MappedSuperclass @SuppressWarnings("serial") public abstract class Parameterized<S, T extends Parameter<S>> extends Metadata { @MapKey(name = "name") @OneToMany(mappedBy = "container", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) @CollectionType(type = "com.sixsq.slipstream.persistence.ConcurrentHashMapType") protected Map<String, T> parameters = new ConcurrentHashMap<String, T>(); /** * parameters accessors have to be overriden to set the valueType value of * the decorator for xml serialization: * @ElementMap(name = "parameters", required = false, valueType = ?) */ @ElementMap(name = "parameters", required = false) abstract protected void setParameters(Map<String, T> parameters); /** * Do not add parameters to the map directly. Instead use setParameter * method * * parameters accessors have to be overriden to set the valueType value of * the decorator for xml serialization: * @ElementMap(name = "parameters", required = false, valueType = ?) */ @ElementMap(name = "parameters", required = false) abstract public Map<String, T> getParameters(); public T getParameter(String name) { return getParameters().get(name); } public String getParameterValue(String name, String defaultValue) { T parameter = getParameter(name); return parameter == null ? defaultValue : parameter.getValue(defaultValue); } public void setParameter(T parameter) throws ValidationException { parameters.put(parameter.getName(), parameter); setContainer(parameter); } // This method is necessary because setting the container directly here // cannot guarantee that the types are correct. public abstract void setContainer(T parameter); public Parameter<S> getParameter(String name, String category) { Parameter<S> parameter = getParameter(name); if (parameter != null && parameter.getCategory().equals(category)) { return parameter; } else { return null; } } public Map<String, Parameter<S>> getParameters(String category) { Map<String, Parameter<S>> filteredParameters = new HashMap<String, Parameter<S>>(); for (Parameter<S> parameter : getParameters().values()) { String pCategory = parameter.getCategory(); if (pCategory.equals(category)) { filteredParameters.put(parameter.getName(), parameter); } } return filteredParameters; } public Collection<T> getParameterList() { return getParameters().values(); } protected void validateParameters() throws ValidationException { for (Entry<String, T> p : getParameters().entrySet()) { p.getValue().validateValue(); } } @SuppressWarnings("unchecked") protected Parameterized<S, T> copyTo(Parameterized<S, T> copy) throws ValidationException { copy = (Parameterized<S, T>) super.copyTo(copy); return copyParametersTo(copy); } protected Parameterized<S, T> copyParametersTo( Parameterized<S, T> parameterized) throws ValidationException { for (T p : getParameters().values()) { @SuppressWarnings("unchecked") T copy = (T) p.copy(); parameterized.setParameter(copy); } return parameterized; } @SuppressWarnings("unchecked") public void postDeserialization() { super.postDeserialization(); // Assign containers inside parameters for (Entry<String, T> p : getParameters().entrySet()) { p.getValue().setContainer((S) this); } } public boolean parametersContainKey(String key) { return (key == null) ? false : getParameters().containsKey(key); } }