/* * RHQ Management Platform * Copyright (C) 2005-2009 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.core.util.updater; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; /** * Provides properties that define metadata about a deployment. * Use the factory method {@link #loadFromFile(File)} to load deployment properties * files. Use {@link #saveToFile(File)} to store deployment properties. * * @author John Mazzitelli */ public class DeploymentProperties extends Properties { private static final long serialVersionUID = 1L; // required properties that must always exist private static final String DEPLOYMENT_ID = "deployment.id"; private static final String BUNDLE_NAME = "bundle.name"; private static final String BUNDLE_VERSION = "bundle.version"; private static final String BUNDLE_DESCRIPTION = "bundle.description"; //note that this really does not make sense as a generic deployment property once we support multiple deployment //units in a bundle. private static final String DESTINATION_COMPLIANCE = "bundle.destination.compliance"; // optional properties /** * @deprecated superseded by destination compliance */ @Deprecated private static final String MANAGE_ROOT_DIR = "manage.root.dir"; public static DeploymentProperties loadFromFile(File file) throws Exception { DeploymentProperties props = new DeploymentProperties(); FileInputStream is = new FileInputStream(file); try { props.load(is); } finally { is.close(); } //Backwards compatibility handling - manageRootDir wasn't required but compliance is.. We need to make the //previously valid files valid now, too, with the original behavior if (props.get(DESTINATION_COMPLIANCE) == null) { props.setDestinationCompliance(DestinationComplianceMode.BACKWARDS_COMPATIBLE_DEFAULT); } props.validate(); return props; } /** * Creates an empty set of deployment properties. The caller must ensure valid * deployment properties are set later. */ public DeploymentProperties() { super(); } /** * Convenience constructor whose parameters are all the required values that * this object needs. * * @param deploymentId see {@link #getDeploymentId()} * @param bundleName see {@link #getBundleName()} * @param bundleVersion see {@link #getBundleVersion()} * @param description see {@link #getDescription()} * * @deprecated use {@link #DeploymentProperties(int, String, String, String, DestinationComplianceMode)}. * This constructor sets the compliance mode to {@link DestinationComplianceMode#full}. */ @Deprecated public DeploymentProperties(int deploymentId, String bundleName, String bundleVersion, String description) { this(deploymentId, bundleName, bundleVersion, description, DestinationComplianceMode.full); } /** * Convenience constructor whose parameters are all the required values that * this object needs. * * @param deploymentId see {@link #getDeploymentId()} * @param bundleName see {@link #getBundleName()} * @param bundleVersion see {@link #getBundleVersion()} * @param description see {@link #getDescription()} * @param destinationCompliance see {@link #getDestinationCompliance()} */ public DeploymentProperties(int deploymentId, String bundleName, String bundleVersion, String description, DestinationComplianceMode destinationCompliance) { setDeploymentId(deploymentId); setBundleName(bundleName); setBundleVersion(bundleVersion); setDescription(description); setDestinationCompliance(destinationCompliance); try { validate(); } catch (Exception e) { throw new IllegalArgumentException(e); } } /** * Returns <code>true</code> if this object has everything required to define a valid deployment. * * @return true if this is valid */ public boolean isValid() { try { validate(); return true; } catch (Exception e) { return false; } } public void saveToFile(File file) throws Exception { validate(); // makes sure we never save invaild properties FileOutputStream os = new FileOutputStream(file); try { store(os, "This file is auto-generated - DO NOT MODIFY!!!"); } finally { os.close(); } return; } private void validate() throws Exception { // all the getters thrown runtime exceptions if the values are not valid, so // just call them all and catch exceptions if they throw them try { getDeploymentId(); getBundleName(); getBundleVersion(); getDescription(); getDestinationCompliance(); } catch (Exception e) { throw new Exception("Deployment properties are invalid: " + e.getMessage()); } } /** * This returns a deployment ID that identifies a known deployment. * If the deployment is not yet known (that is, its going to be a new * deployment added to the system), this will typically return 0. * * @return an identifier that uniquely identifies this particular deployment. */ public int getDeploymentId() { String str = getProperty(DEPLOYMENT_ID); if (str == null) { throw new IllegalStateException("There is no deployment ID"); } try { int id = Integer.parseInt(str); return id; } catch (Exception e) { throw new IllegalStateException("Invalid deployment ID: " + str); } } public void setDeploymentId(int id) { setProperty(DEPLOYMENT_ID, Integer.toString(id)); } /** * @return the name of the bundle for this deployment */ public String getBundleName() { String str = getProperty(BUNDLE_NAME); if (str == null) { throw new IllegalStateException("There is no bundle name"); } return str; } public void setBundleName(String name) { setProperty(BUNDLE_NAME, name); } /** * @return the version of the bundle for this deployment */ public String getBundleVersion() { String str = getProperty(BUNDLE_VERSION); if (str == null) { throw new IllegalStateException("There is no bundle version"); } return str; } public void setBundleVersion(String version) { setProperty(BUNDLE_VERSION, version); } /** * @return the description of this deployment */ public String getDescription() { String str = getProperty(BUNDLE_DESCRIPTION); return str; } public void setDescription(String description) { if (description == null) { remove(BUNDLE_DESCRIPTION); } else { setProperty(BUNDLE_DESCRIPTION, description); } } /** * Note that as of RHQ 4.9.0, this attribute is deprecated. * There is an attempt made to handle reading the old version of the attribute: * <ol> * <li>if "bundle.destination.compliance" attribute is set, base the value on it. If the compliance is "full" * this method returns true, otherwise it returns false.</li> * <li>if "manage.root.dir" attribute is set, base the return value on it (this handles the previous * behavior).</li> * <li>if none of the above attributes is set, return the default value of the deprecated manageRootDir attribute, * which is true.</li> * </ol> * * @return the flag to indicate if the entire root directory content is to be managed. * If there is no property, this method returns a default of <code>true</code> * * @deprecated use {@link #getDestinationCompliance()} */ @Deprecated public boolean getManageRootDir() { DestinationComplianceMode mode = getDestinationComplianceNoException(); if (mode == null) { String str = getProperty(MANAGE_ROOT_DIR); if (str == null) { return true; } return Boolean.parseBoolean(str); } return mode == DestinationComplianceMode.full; } /** * As of RHQ 4.9.0, this is equivalent to {@link #setDestinationCompliance(DestinationComplianceMode) * setDestinationCompliance(willManageRootDir ? DestinationComplianceMode.full : * DestinationComplianceMode.filesAndDirectories)}. * * @param willManageRootDir whether to manage the root directory * * @deprecated use {@link #setDestinationCompliance(DestinationComplianceMode)} instead */ @Deprecated public void setManageRootDir(boolean willManageRootDir) { setDestinationCompliance( willManageRootDir ? DestinationComplianceMode.full : DestinationComplianceMode.filesAndDirectories); } /** * Returns the compliance mode of the destination. This is a required attribute. * * @since 4.9.0 */ public DestinationComplianceMode getDestinationCompliance() { DestinationComplianceMode mode = getDestinationComplianceNoException(); if (mode == null) { throw new IllegalStateException("Destination compliance not specified"); } return mode; } public void setDestinationCompliance(DestinationComplianceMode compliance) { String str = compliance == null ? null : compliance.name(); setProperty(DESTINATION_COMPLIANCE, str); } private DestinationComplianceMode getDestinationComplianceNoException() { String str = getProperty(DESTINATION_COMPLIANCE); if (str == null) { return null; } return Enum.valueOf(DestinationComplianceMode.class, str); } }