001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.jca;
030:
031: import com.caucho.config.ConfigException;
032: import com.caucho.lifecycle.Lifecycle;
033: import com.caucho.server.deploy.DeployController;
034: import com.caucho.server.util.CauchoSystem;
035: import com.caucho.util.L10N;
036: import com.caucho.vfs.Path;
037: import com.caucho.vfs.Vfs;
038:
039: import javax.annotation.PostConstruct;
040: import java.io.IOException;
041: import java.util.ArrayList;
042: import java.util.HashSet;
043: import java.util.Iterator;
044:
045: /**
046: * The generator for the resource-deploy
047: */
048: public class ResourceDeploy {
049: private static final L10N L = new L10N(ResourceDeploy.class);
050:
051: private final ResourceDeployAdmin _admin = new ResourceDeployAdmin(
052: this );
053:
054: private ClassLoader _classLoader;
055:
056: private Path _containerRootDirectory;
057:
058: private Path _rarDir;
059: private Path _rarExpandDir;
060:
061: private String _expandPrefix = "";
062:
063: private HashSet<String> _rarNames = new HashSet<String>();
064:
065: private volatile boolean _isInit;
066:
067: public ResourceDeploy() {
068: _classLoader = Thread.currentThread().getContextClassLoader();
069:
070: setExpandPrefix("_rar_");
071:
072: _containerRootDirectory = Vfs.getPwd();
073:
074: }
075:
076: Path getContainerRootDirectory() {
077: return _containerRootDirectory;
078: }
079:
080: /**
081: * Gets the rar directory.
082: */
083: public Path getPath() {
084: return _rarDir;
085: }
086:
087: /**
088: * Sets the rar directory.
089: */
090: public void setPath(Path path) {
091: _rarDir = path;
092: }
093:
094: public Path getArchiveDirectory() {
095: return getPath();
096: }
097:
098: public Path getArchivePath(String name) {
099: return getArchiveDirectory().lookup(name + getExtension());
100: }
101:
102: /**
103: * Returns the combination of prefix, name, and suffix used for expanded
104: * archives.
105: *
106: * @return
107: */
108: protected String getExpandName(String name) {
109: return getExpandPrefix() + name + getExpandSuffix();
110: }
111:
112: /**
113: * Sets the war expand dir to check for new applications.
114: */
115: public void setExpandPath(Path path) {
116: _rarExpandDir = path;
117: }
118:
119: /**
120: * @deprecated use {@link @getExpandDirectory}
121: */
122: public Path getExpandPath() {
123: return getExpandDirectory();
124: }
125:
126: /**
127: * Gets the rar expand directory.
128: */
129: public Path getExpandDirectory() {
130: if (_rarExpandDir != null)
131: return _rarExpandDir;
132: else
133: return _rarDir;
134: }
135:
136: /**
137: * Returns the location of an expanded archive, or null if no archive with
138: * the passed name is deployed.
139: *
140: * @param name a name, without an extension
141: */
142: public Path getExpandPath(String name) {
143: if (!isDeployedKey(name))
144: return null;
145:
146: return getExpandDirectory().lookup(getExpandName(name));
147: }
148:
149: private boolean isDeployedKey(String name) {
150: return _rarNames.contains(name);
151: }
152:
153: /**
154: * Returns the expand prefix.
155: */
156: public String getExpandPrefix() {
157: return _expandPrefix;
158: }
159:
160: /**
161: * Sets the expand prefix.
162: */
163: public void setExpandPrefix(String prefix) {
164: _expandPrefix = prefix;
165: }
166:
167: public boolean isModified() {
168: try {
169: return !_rarNames.equals(getRarNames());
170: } catch (Exception e) {
171: return false;
172: }
173: }
174:
175: /**
176: * Initialize the resource-deploy.
177: */
178: @PostConstruct
179: public void init() throws ConfigException {
180: synchronized (this ) {
181: if (_isInit)
182: return;
183: _isInit = true;
184: }
185:
186: if (getPath() == null)
187: throw new ConfigException(L
188: .l("resource-deploy requires a path attribute"));
189: deployResources();
190:
191: _admin.register();
192: }
193:
194: private void deployResources() {
195: HashSet<String> oldNames = _rarNames;
196:
197: try {
198: _rarNames = getRarNames();
199:
200: for (String oldName : oldNames) {
201: if (!_rarNames.contains(oldName))
202: undeployResource(oldName);
203: }
204:
205: for (String name : _rarNames) {
206: if (oldNames.contains(name))
207: continue;
208:
209: ResourceArchive rar;
210:
211: rar = new ResourceArchive();
212: rar.setRarPath(getPath().lookup(name + ".rar"));
213: rar.setRootDirectory(getExpandPath().lookup(
214: getExpandPrefix() + name));
215:
216: Path oldPwd = Vfs.getPwd();
217:
218: try {
219: Vfs.setPwd(rar.getRootDirectory());
220:
221: for (ResourceConfig config : ResourceDefault
222: .getDefaultList()) {
223: config.getBuilderProgram().configure(rar);
224: }
225: } finally {
226: Vfs.setPwd(oldPwd);
227: }
228:
229: rar.init();
230:
231: ResourceArchiveManager.addResourceArchive(rar);
232: }
233: } catch (ConfigException e) {
234: throw e;
235: } catch (Exception e) {
236: throw ConfigException.create(e);
237: }
238: }
239:
240: private void undeployResource(String name) {
241: ResourceArchiveManager.removeResourceArchive(name);
242: }
243:
244: /**
245: * Return the war-expansion directories which were added.
246: */
247: private HashSet<String> getRarNames() throws IOException {
248: HashSet<String> rarNames = new HashSet<String>();
249:
250: Path rarDir = getPath();
251: Path rarExpandDir = getExpandPath();
252:
253: if (rarDir == null || rarExpandDir == null)
254: return rarNames;
255:
256: String[] rarDirList = rarDir.list();
257:
258: // collect all the new wars
259: loop: for (int i = 0; i < rarDirList.length; i++) {
260: String rarName = rarDirList[i];
261: String appName;
262:
263: if (!rarName.endsWith(".rar"))
264: continue;
265:
266: Path path = rarDir.lookup(rarName);
267:
268: if (!path.canRead())
269: continue;
270:
271: appName = rarName.substring(0, rarName.length() - 4);
272:
273: if (CauchoSystem.isCaseInsensitive())
274: appName = appName.toLowerCase();
275:
276: rarNames.add(appName);
277: }
278:
279: String[] rarExpandList = rarExpandDir.list();
280: ArrayList<String> newNames = new ArrayList<String>();
281:
282: // collect all the new rar expand directories
283: loop: for (int i = 0; i < rarExpandList.length; i++) {
284: String rarDirName = rarExpandList[i];
285:
286: if (!rarDirName.startsWith(getExpandPrefix()))
287: continue;
288:
289: if (CauchoSystem.isCaseInsensitive())
290: rarDirName = rarDirName.toLowerCase();
291:
292: Path path = rarExpandDir.lookup(rarDirName);
293:
294: if (!path.isDirectory()
295: || !rarDirName.startsWith(getExpandPrefix()))
296: continue;
297:
298: String appName = rarDirName.substring(getExpandPrefix()
299: .length());
300:
301: if (!newNames.contains(appName))
302: newNames.add(appName);
303:
304: rarNames.add(appName);
305: }
306:
307: return rarNames;
308: }
309:
310: public String getExtension() {
311: return ".rar";
312: }
313:
314: public String getExpandSuffix() {
315: return "";
316: }
317:
318: public long getDependencyCheckInterval() {
319: return -1;
320: }
321:
322: public String getStartupMode() {
323: return DeployController.STARTUP_AUTOMATIC;
324: }
325:
326: public String getRedeployMode() {
327: return DeployController.REDEPLOY_MANUAL;
328: }
329:
330: public String getState() {
331: if (!_isInit)
332: return Lifecycle.getStateName(Lifecycle.IS_NEW);
333: else
334: return Lifecycle.getStateName(Lifecycle.IS_ACTIVE);
335: }
336:
337: public void start() {
338: // XXX:
339: }
340:
341: public Throwable getConfigException() {
342: // XXX:
343: return null;
344: }
345:
346: public void stop() {
347: // XXX:
348: }
349:
350: public void update() {
351: // XXX:
352: }
353:
354: public String[] getNames() {
355: // XXX:
356: return new String[0];
357: }
358:
359: public void stop(String name) {
360: // XXX:
361: }
362:
363: public void start(String name) {
364: Thread thread = Thread.currentThread();
365: ClassLoader oldLoader = thread.getContextClassLoader();
366:
367: try {
368: thread.setContextClassLoader(_classLoader);
369:
370: deployResources();
371: } finally {
372: thread.setContextClassLoader(oldLoader);
373: }
374: }
375:
376: public Throwable getConfigException(String moduleID) {
377: // XXX:
378: return null;
379: }
380:
381: public void undeploy(String name) {
382: // XXX:
383: }
384:
385: }
|