001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.services.deployment;
019:
020: import org.sape.carbon.core.component.ComponentConfiguration;
021: import org.sape.carbon.core.component.lifecycle.Configurable;
022: import org.sape.carbon.core.component.lifecycle.Startable;
023: import org.sape.carbon.core.component.lifecycle.Suspendable;
024: import org.sape.carbon.core.config.Config;
025: import org.sape.carbon.core.config.InvalidConfigurationException;
026: import org.sape.carbon.core.config.node.Folder;
027: import org.sape.carbon.core.config.node.Node;
028: import org.sape.carbon.core.config.node.NodeCreationException;
029: import org.sape.carbon.core.config.node.NodeNotFoundException;
030: import org.sape.carbon.core.config.node.NodeRemovalException;
031: import org.sape.carbon.core.config.node.link.GenericLinkNodeConfiguration;
032: import org.sape.carbon.core.config.node.link.GenericLinkNodeFactory;
033:
034: import org.sape.carbon.services.deployment.namelookup.*;
035:
036: /**
037: * This implementation of <code>DeploymentService</code> uses
038: * BootStrapper.getEnvironmentName and BootStrapper.getInstanceName to
039: * determine which environment and instance the current deployment is.
040: *
041: * @since carbon 1.0
042: * @author Douglas Voet, April 2002
043: * @version $Revision: 1.16 $($Author: dvoet $ / $Date: 2003/09/24 20:31:11 $)
044: * <br>Copyright 2002 Sapient
045: */
046: public class DefaultDeploymentServiceImpl implements DeploymentService,
047: Configurable, Startable, Suspendable {
048:
049: /** Holds a reference to the Node that contains deployment information. */
050: protected Folder deploymentsNode;
051:
052: /** Holds name of the current deployment node. */
053: protected String currentDeploymentNodeName;
054:
055: /** Holds the name of the node with current deployment info. */
056: protected String targetNodeName;
057:
058: /**
059: * Fetches the deployment node and stores the CurrentDeploymentNodeName
060: * @see Configurable#configure(ComponentConfiguration)
061: */
062: public void configure(ComponentConfiguration configuration)
063: throws DeploymentServiceException {
064:
065: DeploymentServiceConfiguration deploymentConfiguration = (DeploymentServiceConfiguration) configuration;
066:
067: try {
068: this .deploymentsNode = (Folder) Config.getInstance()
069: .fetchNode(
070: deploymentConfiguration
071: .getDeploymentsNodeAbsoluteName());
072: } catch (NodeNotFoundException nnfe) {
073: throw new InvalidConfigurationException(this .getClass(),
074: configuration.getConfigurationName(),
075: "DeploymentsNodeAbsoluteName", nnfe);
076: }
077:
078: this .currentDeploymentNodeName = deploymentConfiguration
079: .getCurrentDeploymentNodeName();
080:
081: this .targetNodeName = constructTargetNodeName(configuration);
082: }
083:
084: /**
085: * Creates the link to the current deployment.
086: * @see Startable#start()
087: */
088: public void start() throws DeploymentServiceException {
089: createDeploymentLink();
090: }
091:
092: /**
093: * @see Startable#stop()
094: */
095: public void stop() {
096: }
097:
098: /**
099: * Assumes the service has been reconfigured and recreates the link to
100: * the current deployment.
101: * @see Suspendable#resume()
102: */
103: public void resume() throws DeploymentServiceException {
104: // assume the service was reconfigured recreate the
105: // current deployment link
106: createDeploymentLink();
107: }
108:
109: /**
110: * @see Suspendable#suspend()
111: */
112: public void suspend() {
113: }
114:
115: /**
116: * Helper method that does the work of creating the link to the
117: * current deployment configuration.
118: *
119: * @throws DeploymentServiceException indicates an error creating
120: * the deployment link.
121: */
122: protected void createDeploymentLink()
123: throws DeploymentServiceException {
124:
125: try {
126: GenericLinkNodeConfiguration linkConfiguration = (GenericLinkNodeConfiguration) Config
127: .getInstance().createConfiguration(
128: GenericLinkNodeConfiguration.class);
129:
130: linkConfiguration
131: .setLinkNodeFactoryClass(GenericLinkNodeFactory.class);
132:
133: linkConfiguration.setTargetNodeName(this .targetNodeName);
134:
135: if (this .deploymentsNode
136: .containsChild(this .currentDeploymentNodeName)) {
137:
138: this .deploymentsNode.fetchChild(
139: this .currentDeploymentNodeName).remove();
140: }
141:
142: this .deploymentsNode.addLink(
143: this .currentDeploymentNodeName, linkConfiguration);
144:
145: } catch (NodeRemovalException nre) {
146: throw new DeploymentServiceException(this .getClass(),
147: "Could not remove existing current deployment "
148: + "link: ["
149: + this .deploymentsNode.getAbsoluteName()
150: + Node.DELIMITER
151: + this .currentDeploymentNodeName + "]", nre);
152:
153: } catch (NodeNotFoundException nnfe) {
154: // this should never happen
155: // cause is probably a bug in Folder implementation
156: throw new DeploymentServiceException(
157: this .getClass(),
158: "Inconsistent results from Folder: containsChild "
159: + "returned true, but fetch threw NodeNotFoundException",
160: nnfe);
161:
162: } catch (NodeCreationException nce) {
163: throw new DeploymentServiceException(this .getClass(),
164: "Could not create current deployment link: ["
165: + this .deploymentsNode.getAbsoluteName()
166: + Node.DELIMITER
167: + this .currentDeploymentNodeName + "]", nce);
168: }
169: }
170:
171: /**
172: * Helper method that constructs the name of the node that will be used
173: * as the target of the deployment link. This node holds the actual
174: * configuration values that will be used in this deployment. This method
175: * is called from the configure lifecycle method. Override this method
176: * to change how the target node name is constructed.
177: *
178: * @param serviceConfig the configuration for this service (the config
179: * passed into the configure method)
180: * @return the path to the node that should be the target of the deployment
181: * link. Although it is not required, this should be a relative path.
182: */
183: protected String constructTargetNodeName(
184: ComponentConfiguration serviceConfig)
185: throws DeploymentServiceException {
186:
187: DeploymentServiceConfiguration deploymentConfiguration = (DeploymentServiceConfiguration) serviceConfig;
188:
189: String environmentName = deploymentConfiguration
190: .getEnvironmentName();
191: NameLookup environmentNameLookup = deploymentConfiguration
192: .getEnvironmentNameLookup();
193:
194: String instanceName = deploymentConfiguration.getInstanceName();
195: NameLookup instanceNameLookup = deploymentConfiguration
196: .getInstanceNameLookup();
197:
198: // validate configuration
199: // both environmentName and environmentNameLookup cannot be null
200: if ((environmentName == null || "".equals(environmentName))
201: && environmentNameLookup == null) {
202: throw new InvalidConfigurationException(this .getClass(),
203: serviceConfig.getConfigurationName(),
204: "EnvironmentName or EnvironmentNameLookup",
205: "Neither EnvironmentName nor EnvironmentNameLookup were specified");
206: }
207:
208: // only one of environmentName or environmentNameLookup can be specified
209: if ((environmentName != null && !"".equals(environmentName))
210: && environmentNameLookup != null) {
211: throw new InvalidConfigurationException(this .getClass(),
212: serviceConfig.getConfigurationName(),
213: "EnvironmentName or EnvironmentNameLookup",
214: "Only one of EnvironmentName and EnvironmentNameLookup can be specified");
215: }
216:
217: // only one of instanceName or instanceNameLookup can be specified
218: if ((instanceName != null && !"".equals(instanceName))
219: && instanceNameLookup != null) {
220: throw new InvalidConfigurationException(this .getClass(),
221: serviceConfig.getConfigurationName(),
222: "InstanceName or InstanceNameLookup",
223: "Only one of InstanceName and InstanceNameLookup can be specified");
224: }
225:
226: // contruct name
227: StringBuffer nodeName = new StringBuffer();
228: if (environmentNameLookup != null) {
229: nodeName.append(environmentNameLookup.lookupName());
230: } else {
231: nodeName.append(environmentName);
232: }
233:
234: if (instanceNameLookup != null) {
235: nodeName.append(Node.DELIMITER);
236: nodeName.append(instanceNameLookup.lookupName());
237: } else if (instanceName != null && !"".equals(instanceName)) {
238: nodeName.append(Node.DELIMITER);
239: nodeName.append(instanceName);
240: }
241:
242: return nodeName.toString();
243: }
244: }
|