001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.deployment.cache;
023:
024: import java.net.URL;
025:
026: import javax.management.ObjectName;
027: import javax.management.MBeanServer;
028:
029: import org.jboss.system.ServiceMBeanSupport;
030: import org.jboss.system.MissingAttributeException;
031:
032: import org.jboss.deployment.Deployer;
033: import org.jboss.deployment.DeploymentException;
034:
035: import org.jboss.util.NullArgumentException;
036: import org.jboss.mx.util.MBeanProxyExt;
037: import org.jboss.mx.util.MBeanProxyInstance;
038:
039: /**
040: * A Deployer-like service which intercepts deploy/undeploy calls
041: * to MainDeployer and provides local caching of target URLs using
042: * local disk.
043: *
044: * @jmx:mbean extends="org.jboss.system.ServiceMBean, org.jboss.deployment.DeployerMBean"
045: *
046: * @todo clean up stale cache members
047: *
048: * @version <tt>$Revision: 57205 $</tt>
049: * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
050: */
051: public class DeploymentCache extends ServiceMBeanSupport implements
052: Deployer, DeploymentCacheMBean {
053: /** A proxy to the deployer we are using. */
054: protected Deployer deployer;
055:
056: /** A proxy to the deployment store we are using. */
057: protected DeploymentStore store;
058:
059: /////////////////////////////////////////////////////////////////////////
060: // Pluggables //
061: /////////////////////////////////////////////////////////////////////////
062:
063: /**
064: * @jmx:managed-attribute
065: */
066: public void setDeployer(final ObjectName deployerName) {
067: if (deployerName == null)
068: throw new NullArgumentException("deployerName");
069:
070: deployer = (Deployer) MBeanProxyExt.create(Deployer.class,
071: deployerName, server);
072: }
073:
074: /**
075: * @jmx:managed-attribute
076: */
077: public ObjectName getDeployer() {
078: return ((MBeanProxyInstance) deployer)
079: .getMBeanProxyObjectName();
080: }
081:
082: /**
083: * @jmx:managed-attribute
084: */
085: public void setStore(final ObjectName storeName) {
086: if (storeName == null)
087: throw new NullArgumentException("storeName");
088:
089: store = (DeploymentStore) MBeanProxyExt.create(
090: DeploymentStore.class, storeName, server);
091: }
092:
093: /**
094: * @jmx:managed-attribute
095: */
096: public ObjectName getStore() {
097: return ((MBeanProxyInstance) store).getMBeanProxyObjectName();
098: }
099:
100: /////////////////////////////////////////////////////////////////////////
101: // Deployer //
102: /////////////////////////////////////////////////////////////////////////
103:
104: protected boolean isInvalid(final URL orig, final URL stored)
105: throws Exception {
106: boolean trace = log.isTraceEnabled();
107:
108: long omod = orig.openConnection().getLastModified();
109: long smod = stored.openConnection().getLastModified();
110:
111: if (trace) {
112: log.trace("Modfication times (orig, stored): " + omod
113: + ", " + smod);
114: }
115:
116: return omod > smod;
117: }
118:
119: public void deploy(final URL url) throws DeploymentException {
120: boolean debug = log.isDebugEnabled();
121:
122: try {
123: URL storedURL = store.get(url);
124: if (storedURL != null) {
125: // it's in the cache, is it still valid ?
126:
127: if (isInvalid(url, storedURL)) {
128: // the stored version is old, get the new version
129: log
130: .info("Cached deployment is invalid; refreshing store for URL: "
131: + url);
132: storedURL = store.put(url);
133: } else {
134: if (debug) {
135: log.debug("Using cached deployment URL: "
136: + storedURL);
137: }
138: }
139: } else {
140: // not in the cache, put it there
141: log
142: .info("Deployment not in cache; adding URL to store: "
143: + url);
144: storedURL = store.put(url);
145: }
146:
147: // invoke the chained deployer with the stored URL
148: deployer.deploy(storedURL);
149: } catch (Exception e) {
150: throw new DeploymentException(e);
151: }
152: }
153:
154: public void undeploy(final URL url) throws DeploymentException {
155: boolean debug = log.isDebugEnabled();
156:
157: try {
158: URL storedURL = store.get(url);
159: if (storedURL != null) {
160: // invoke undeploy on target deployer using local cache url
161: deployer.undeploy(storedURL);
162: } else {
163: if (debug) {
164: log.debug("Not found in store; ignoring URL: "
165: + url);
166: }
167: }
168: } catch (Exception e) {
169: throw new DeploymentException(e);
170: }
171: }
172:
173: public boolean isDeployed(final URL url) {
174: try {
175: URL storedURL = store.get(url);
176:
177: // if the stored url is not null then ask the target deployer
178: // else it is not deployed
179: return storedURL != null && deployer.isDeployed(url);
180: } catch (Exception e) {
181: return false;
182: }
183: }
184:
185: /////////////////////////////////////////////////////////////////////////
186: // Service/ServiceMBeanSupport //
187: /////////////////////////////////////////////////////////////////////////
188:
189: protected void createService() throws Exception {
190: // create stale deployemnt timer/scanner/whatever
191: }
192:
193: protected void startService() throws Exception {
194: if (deployer == null)
195: throw new MissingAttributeException("Deployer");
196: if (store == null)
197: throw new MissingAttributeException("Store");
198:
199: // start stale deployemnt timer/scanner/whatever
200: }
201:
202: protected void stopService() throws Exception {
203: // stop stale deployemnt timer/scanner/whatever
204: }
205:
206: protected void destroyService() throws Exception {
207: deployer = null;
208: store = null;
209: }
210: }
|