0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.server.deploy;
0031:
0032: import com.caucho.config.ConfigException;
0033: import com.caucho.config.types.FileSetType;
0034: import com.caucho.config.types.Period;
0035: import com.caucho.loader.Environment;
0036: import com.caucho.log.Log;
0037: import com.caucho.util.Alarm;
0038: import com.caucho.util.AlarmListener;
0039: import com.caucho.util.L10N;
0040: import com.caucho.util.WeakAlarm;
0041: import com.caucho.server.util.CauchoSystem;
0042: import com.caucho.vfs.Path;
0043:
0044: import java.io.IOException;
0045: import java.util.ArrayList;
0046: import java.util.Set;
0047: import java.util.TreeSet;
0048: import java.util.TreeMap;
0049: import java.util.logging.Level;
0050: import java.util.logging.Logger;
0051:
0052: /**
0053: * The generator for the deploy
0054: */
0055: abstract public class ExpandDeployGenerator<E extends ExpandDeployController>
0056: extends DeployGenerator<E> implements AlarmListener {
0057: private static final Logger log = Logger
0058: .getLogger(ExpandDeployGenerator.class.getName());
0059: private static final L10N L = new L10N(ExpandDeployGenerator.class);
0060:
0061: private static final long MIN_CRON_INTERVAL = 5000L;
0062:
0063: private Path _path; // default path
0064:
0065: private Path _containerRootDirectory;
0066: private Path _archiveDirectory;
0067: private Path _expandDirectory;
0068:
0069: private String _extension = ".jar";
0070:
0071: private String _expandPrefix = "";
0072: private String _expandSuffix = "";
0073:
0074: private boolean _isVersioning;
0075:
0076: private ArrayList<String> _requireFiles = new ArrayList<String>();
0077:
0078: private TreeSet<String> _controllerNames = new TreeSet<String>();
0079:
0080: private TreeMap<String, ArrayList<String>> _versionMap = new TreeMap<String, ArrayList<String>>();
0081:
0082: private FileSetType _expandCleanupFileSet;
0083:
0084: private Alarm _alarm;
0085: private long _cronInterval;
0086:
0087: private volatile long _lastCheckTime;
0088: private volatile boolean _isChecking;
0089: private long _checkInterval = 1000L;
0090: private long _digest;
0091: private volatile boolean _isModified;
0092: private volatile boolean _isDeploying;
0093:
0094: /**
0095: * Creates the deploy.
0096: */
0097: public ExpandDeployGenerator(DeployContainer<E> container,
0098: Path containerRootDirectory) {
0099: super (container);
0100:
0101: _containerRootDirectory = containerRootDirectory;
0102:
0103: _alarm = new WeakAlarm(this );
0104:
0105: _cronInterval = Environment.getDependencyCheckInterval();
0106: if (_cronInterval < MIN_CRON_INTERVAL)
0107: _cronInterval = MIN_CRON_INTERVAL;
0108: }
0109:
0110: Path getContainerRootDirectory() {
0111: return _containerRootDirectory;
0112: }
0113:
0114: /**
0115: * Gets the default path.
0116: */
0117: public Path getPath() {
0118: return _path;
0119: }
0120:
0121: /**
0122: * Sets the deploy directory.
0123: */
0124: public void setPath(Path path) {
0125: _path = path;
0126: }
0127:
0128: /**
0129: * Sets the war expand dir to check for new applications.
0130: */
0131: public void setExpandPath(Path path) {
0132: log
0133: .config("Use <expand-directory> instead of <expand-path>. <expand-path> is deprecated.");
0134:
0135: setExpandDirectory(path);
0136: }
0137:
0138: /**
0139: * Sets the war expand dir to check for new applications.
0140: */
0141: public void setExpandDirectory(Path path) {
0142: _expandDirectory = path;
0143: }
0144:
0145: /**
0146: * Gets the war expand directory.
0147: */
0148: public Path getExpandDirectory() {
0149: if (_expandDirectory != null)
0150: return _expandDirectory;
0151: else
0152: return _path;
0153: }
0154:
0155: /**
0156: * Returns the location of an expanded archive, or null if no archive with
0157: * the passed name is deployed.
0158: *
0159: * @param name a name, without an extension
0160: */
0161: public Path getExpandPath(String name) {
0162: if (!isDeployedKey(nameToEntryName(name)))
0163: return null;
0164:
0165: return getExpandDirectory().lookup(getExpandName(name));
0166:
0167: /*
0168: if (expandDir.isDirectory())
0169: return expandDir;
0170:
0171: Path extPath = getExpandDirectory().lookup(name + _extension);
0172:
0173: if (extPath.isDirectory())
0174: return extPath;
0175: else
0176: return expandDir;
0177: */
0178: }
0179:
0180: /**
0181: * Returns the combination of prefix, name, and suffix used for expanded
0182: * archives.
0183: *
0184: * @return
0185: */
0186: protected String getExpandName(String name) {
0187: return getExpandPrefix() + name + getExpandSuffix();
0188: }
0189:
0190: /**
0191: * Sets the war expand dir to check for new archive files.
0192: */
0193: public void setArchiveDirectory(Path path) {
0194: _archiveDirectory = path;
0195: }
0196:
0197: /**
0198: * Gets the war expand directory.
0199: */
0200: public Path getArchiveDirectory() {
0201: if (_archiveDirectory != null)
0202: return _archiveDirectory;
0203: else
0204: return _path;
0205: }
0206:
0207: /**
0208: * Returns the location for deploying an archive with the specified name.
0209: *
0210: * @param name a name, without an extension
0211: */
0212: public Path getArchivePath(String name) {
0213: return getArchiveDirectory().lookup(name + getExtension());
0214: }
0215:
0216: /**
0217: * Sets the dependency check interval.
0218: */
0219: public void setDependencyCheckInterval(Period period) {
0220: _cronInterval = period.getPeriod();
0221:
0222: if (_cronInterval < 0)
0223: _cronInterval = Period.INFINITE;
0224: else if (_cronInterval < MIN_CRON_INTERVAL)
0225: _cronInterval = MIN_CRON_INTERVAL;
0226: }
0227:
0228: public long getDependencyCheckInterval() {
0229: return _cronInterval;
0230: }
0231:
0232: /**
0233: * Sets the expand remove file set.
0234: */
0235: public void setExpandCleanupFileset(FileSetType fileSet) {
0236: _expandCleanupFileSet = fileSet;
0237: }
0238:
0239: /**
0240: * Sets the extension.
0241: */
0242: public void setExtension(String extension) throws ConfigException {
0243: if (!extension.startsWith("."))
0244: throw new ConfigException(L.l(
0245: "deployment extension '{0}' must begin with '.'",
0246: extension));
0247:
0248: _extension = extension;
0249: }
0250:
0251: /**
0252: * Returns the extension.
0253: */
0254: public String getExtension() {
0255: return _extension;
0256: }
0257:
0258: /**
0259: * Sets the expand prefix to check for new applications.
0260: */
0261: public void setExpandPrefix(String prefix) throws ConfigException {
0262: if (!prefix.equals("") && !prefix.startsWith("_")
0263: && !prefix.startsWith("."))
0264: throw new ConfigException(L.l(
0265: "expand-prefix '{0}' must start with '.' or '_'.",
0266: prefix));
0267:
0268: _expandPrefix = prefix;
0269: }
0270:
0271: /**
0272: * Gets the expand prefix.
0273: */
0274: public String getExpandPrefix() {
0275: return _expandPrefix;
0276: }
0277:
0278: /**
0279: * Sets the expand suffix to check for new applications.
0280: */
0281: public void setExpandSuffix(String suffix) throws ConfigException {
0282: _expandSuffix = suffix;
0283: }
0284:
0285: /**
0286: * Gets the expand suffix.
0287: */
0288: public String getExpandSuffix() {
0289: return _expandSuffix;
0290: }
0291:
0292: /**
0293: * Adds a required file in the expansion.
0294: */
0295: public void addRequireFile(String file) throws ConfigException {
0296: _requireFiles.add(file);
0297: }
0298:
0299: /**
0300: * Sets true to enable versioning
0301: */
0302: public void setVersioning(boolean isVersioning) {
0303: _isVersioning = isVersioning;
0304: }
0305:
0306: /**
0307: * Sets true to enable versioning
0308: */
0309: public boolean isVersioning() {
0310: return _isVersioning;
0311: }
0312:
0313: /**
0314: * Returns the log.
0315: */
0316: protected Logger getLog() {
0317: return log;
0318: }
0319:
0320: /**
0321: * Returns true if the deployment has modified.
0322: */
0323: @Override
0324: public boolean isModified() {
0325: synchronized (this ) {
0326: long now = Alarm.getCurrentTime();
0327:
0328: if (now < _lastCheckTime + _checkInterval || _isChecking) {
0329: return _isModified;
0330: }
0331:
0332: _isChecking = true;
0333: _lastCheckTime = Alarm.getCurrentTime();
0334: }
0335:
0336: try {
0337: long digest = getDigest();
0338:
0339: _isModified = _digest != digest;
0340:
0341: return _isModified;
0342: } catch (Exception e) {
0343: log.log(Level.FINE, e.toString(), e);
0344:
0345: return false;
0346: } finally {
0347: _isChecking = false;
0348: }
0349: }
0350:
0351: /**
0352: * Log the reason for modification
0353: */
0354: @Override
0355: public boolean logModified(Logger log) {
0356: long digest = getDigest();
0357:
0358: if (_digest != digest) {
0359: String reason = "";
0360:
0361: String name = getClass().getName();
0362: int p = name.lastIndexOf('.');
0363: if (p > 0)
0364: name = name.substring(p + 1);
0365:
0366: Path archiveDirectory = getArchiveDirectory();
0367: if (archiveDirectory != null)
0368: reason = name + "[" + archiveDirectory.getNativePath()
0369: + "] is modified";
0370:
0371: Path expandDirectory = getExpandDirectory();
0372: if (expandDirectory != null
0373: && !expandDirectory.equals(archiveDirectory)) {
0374: if (!"".equals(reason))
0375: reason = reason + " or ";
0376:
0377: reason = name + "[" + expandDirectory.getNativePath()
0378: + "] is modified";
0379: }
0380:
0381: log.info(reason);
0382:
0383: return true;
0384: }
0385:
0386: return false;
0387: }
0388:
0389: /**
0390: * Configuration checks on init.
0391: */
0392: @Override
0393: protected void initImpl() throws ConfigException {
0394: super .initImpl();
0395:
0396: if (getExpandDirectory() == null)
0397: throw new ConfigException(
0398: L
0399: .l("<expand-directory> must be specified for deployment of archive expansion."));
0400:
0401: if (getArchiveDirectory() == null)
0402: throw new ConfigException(
0403: L
0404: .l("<archive-directory> must be specified for deployment of archive expansion."));
0405: }
0406:
0407: /**
0408: * Starts the deploy.
0409: */
0410: @Override
0411: protected void startImpl() {
0412: super .startImpl();
0413:
0414: handleAlarm(_alarm);
0415: }
0416:
0417: /**
0418: * Returns the deployed keys.
0419: */
0420: protected void fillDeployedKeys(Set<String> keys) {
0421: if (isModified()) {
0422: try {
0423: deploy();
0424: } catch (Throwable e) {
0425: log.log(Level.WARNING, e.toString(), e);
0426: }
0427: }
0428:
0429: for (String name : _controllerNames) {
0430: keys.add(name);
0431: }
0432: }
0433:
0434: /**
0435: * Return true for a matching key.
0436: */
0437: protected boolean isDeployedKey(String key) {
0438: return _controllerNames.contains(key);
0439: }
0440:
0441: /**
0442: * Forces an update.
0443: */
0444: public void update() {
0445: // force modify check
0446: _lastCheckTime = 0;
0447:
0448: request();
0449: }
0450:
0451: /**
0452: * Redeploys if modified.
0453: */
0454: public void request() {
0455: if (isModified()) {
0456: try {
0457: deploy();
0458: } catch (Throwable e) {
0459: log.log(Level.WARNING, e.toString(), e);
0460: }
0461: }
0462: }
0463:
0464: /**
0465: * Deploys the objects.
0466: */
0467: private void deploy() throws Exception {
0468: boolean isDeploying = false;
0469:
0470: log.finer(this + " redeploy " + _isDeploying);
0471:
0472: try {
0473: ArrayList<String> updatedNames = null;
0474:
0475: synchronized (this ) {
0476: if (_isDeploying)
0477: return;
0478: else {
0479: _isDeploying = true;
0480: isDeploying = true;
0481: }
0482:
0483: TreeSet<String> entryNames = findEntryNames();
0484:
0485: _digest = getDigest();
0486:
0487: if (!_controllerNames.equals(entryNames)) {
0488: updatedNames = new ArrayList<String>();
0489:
0490: for (String name : _controllerNames) {
0491: if (!entryNames.contains(name))
0492: updatedNames.add(name);
0493: }
0494:
0495: for (String name : entryNames) {
0496: if (!_controllerNames.contains(name))
0497: updatedNames.add(name);
0498: }
0499:
0500: _controllerNames = entryNames;
0501: }
0502: }
0503:
0504: for (int i = 0; updatedNames != null
0505: && i < updatedNames.size(); i++) {
0506: String name = updatedNames.get(i);
0507:
0508: getDeployContainer().update(name);
0509: }
0510: } finally {
0511: if (isDeploying) {
0512: _isModified = false;
0513: _isDeploying = false;
0514: }
0515: }
0516: }
0517:
0518: /**
0519: * Finds the matching entry.
0520: */
0521: public E generateController(String name) {
0522: request();
0523:
0524: Thread thread = Thread.currentThread();
0525: ClassLoader oldLoader = thread.getContextClassLoader();
0526: try {
0527: thread.setContextClassLoader(getParentClassLoader());
0528:
0529: E controller = createController(name);
0530:
0531: if (controller != null) {
0532: controller
0533: .setExpandCleanupFileSet(_expandCleanupFileSet);
0534:
0535: _controllerNames.add(name); // server/1d19
0536: }
0537:
0538: return controller;
0539: } finally {
0540: thread.setContextClassLoader(oldLoader);
0541: }
0542: }
0543:
0544: /**
0545: * Returns the digest of the expand and archive directories.
0546: */
0547: private long getDigest() {
0548: long archiveDigest = 0;
0549:
0550: Path archiveDirectory = getArchiveDirectory();
0551: if (archiveDirectory != null)
0552: archiveDigest = archiveDirectory.getCrc64();
0553:
0554: long expandDigest = 0;
0555:
0556: Path expandDirectory = getExpandDirectory();
0557: if (expandDirectory != null)
0558: expandDigest = expandDirectory.getCrc64();
0559:
0560: return archiveDigest * 65521 + expandDigest;
0561: }
0562:
0563: public ArrayList<String> getVersionNames(String name) {
0564: if (!isVersioning())
0565: return null;
0566:
0567: TreeSet<String> entryNames;
0568:
0569: try {
0570: entryNames = findEntryNames();
0571: } catch (IOException e) {
0572: throw new RuntimeException(e);
0573: }
0574:
0575: TreeMap<String, ArrayList<String>> versionMap = buildVersionMap(entryNames);
0576:
0577: return versionMap.get(name);
0578: }
0579:
0580: /**
0581: * Return the entry names for all deployed objects.
0582: */
0583: private TreeSet<String> findEntryNames() throws IOException {
0584: TreeSet<String> entryNames = new TreeSet<String>();
0585:
0586: Path archiveDirectory = getArchiveDirectory();
0587: Path expandDirectory = getExpandDirectory();
0588:
0589: if (archiveDirectory == null || expandDirectory == null)
0590: return entryNames;
0591:
0592: String[] entryList = archiveDirectory.list();
0593:
0594: // collect all the new entrys
0595: loop: for (int i = 0; i < entryList.length; i++) {
0596: String archiveName = entryList[i];
0597:
0598: Path archivePath = archiveDirectory.lookup(archiveName);
0599:
0600: String entryName = null;
0601:
0602: if (!archivePath.canRead())
0603: continue;
0604: else
0605: entryName = archiveNameToEntryName(archiveName);
0606:
0607: if (entryName != null) {
0608: entryNames.add(entryName);
0609:
0610: if (_isVersioning) {
0611: int p = entryName.lastIndexOf('-');
0612:
0613: if (p >= 0) {
0614: entryName = entryName.substring(0, p);
0615:
0616: if (!entryNames.contains(entryName))
0617: entryNames.add(entryName);
0618: }
0619: }
0620: }
0621: }
0622:
0623: String[] entryExpandList = expandDirectory.list();
0624:
0625: // collect all the new war expand directories
0626: loop: for (int i = 0; i < entryExpandList.length; i++) {
0627: String pathName = entryExpandList[i];
0628:
0629: /* XXX: this used to be needed to solve issues with NT
0630: if (CauchoSystem.isCaseInsensitive())
0631: pathName = pathName.toLowerCase();
0632: */
0633:
0634: Path rootDirectory = expandDirectory.lookup(pathName);
0635:
0636: String entryName = pathNameToEntryName(pathName);
0637:
0638: if (entryName == null)
0639: continue;
0640: else if (entryName.endsWith(getExtension()))
0641: continue;
0642:
0643: if (!isValidDirectory(rootDirectory, pathName))
0644: continue;
0645:
0646: if (!entryNames.contains(entryName))
0647: entryNames.add(entryName);
0648:
0649: if (_isVersioning) {
0650: int p = entryName.lastIndexOf('-');
0651:
0652: if (p >= 0) {
0653: entryName = entryName.substring(0, p);
0654:
0655: if (!entryNames.contains(entryName))
0656: entryNames.add(entryName);
0657: }
0658: }
0659: }
0660:
0661: return entryNames;
0662: }
0663:
0664: /**
0665: * Return the entry names for all deployed objects.
0666: */
0667: private TreeMap<String, ArrayList<String>> buildVersionMap(
0668: TreeSet<String> entryNames) {
0669: TreeMap<String, ArrayList<String>> versionMap;
0670: versionMap = new TreeMap<String, ArrayList<String>>();
0671:
0672: for (String name : entryNames) {
0673: String baseName = versionedNameToBaseName(name);
0674:
0675: if (_isVersioning && !baseName.equals(name)) {
0676: ArrayList<String> list = versionMap.get(baseName);
0677: if (list == null)
0678: list = new ArrayList<String>();
0679:
0680: list.add(name);
0681:
0682: versionMap.put(baseName, list);
0683: }
0684: }
0685:
0686: return versionMap;
0687: }
0688:
0689: protected boolean isValidDirectory(Path rootDirectory,
0690: String pathName) {
0691:
0692: if (!rootDirectory.isDirectory() || pathName.startsWith(".")) {
0693: return false;
0694: }
0695:
0696: if (pathName.equalsIgnoreCase("web-inf")
0697: || pathName.equalsIgnoreCase("meta-inf"))
0698: return false;
0699:
0700: for (int j = 0; j < _requireFiles.size(); j++) {
0701: String file = _requireFiles.get(j);
0702:
0703: if (!rootDirectory.lookup(file).canRead())
0704: return false;
0705: }
0706:
0707: return true;
0708: }
0709:
0710: /**
0711: * Converts the expand-path name to the entry name, returns null if
0712: * the path name is not valid.
0713: */
0714: protected String pathNameToEntryName(String name) {
0715: if (_expandPrefix == null) {
0716: } else if (_expandPrefix.equals("")
0717: && (name.startsWith("_") || name.startsWith(".")
0718: || name.endsWith(".")
0719: && CauchoSystem.isWindows()
0720: || name.equalsIgnoreCase("META-INF") || name
0721: .equalsIgnoreCase("WEB-INF"))) {
0722: return null;
0723: } else if (name.startsWith(_expandPrefix)) {
0724: name = name.substring(_expandPrefix.length());
0725: } else
0726: return null;
0727:
0728: if (_expandSuffix == null || "".equals(_expandSuffix)) {
0729: } else if (name.endsWith(_expandSuffix))
0730: return name.substring(0, name.length()
0731: - _expandSuffix.length());
0732: else
0733: return null;
0734:
0735: if (_extension != null && name.endsWith(_extension))
0736: return name.substring(0, name.length()
0737: - _extension.length());
0738: else
0739: return name;
0740: }
0741:
0742: /**
0743: * Converts the archive name to the entry name, returns null if
0744: * the archive name is not valid.
0745: */
0746: protected String entryNameToArchiveName(String entryName) {
0747: return entryName + getExtension();
0748: }
0749:
0750: /**
0751: * Converts the entry name to the archive name, returns null if
0752: * the entry name is not valid.
0753: */
0754: protected String archiveNameToEntryName(String archiveName) {
0755: if (!archiveName.endsWith(_extension))
0756: return null;
0757: else {
0758: int sublen = archiveName.length() - _extension.length();
0759: return pathNameToEntryName(archiveName.substring(0, sublen));
0760: }
0761: }
0762:
0763: /**
0764: * Creates a new entry.
0765: */
0766: abstract protected E createController(String name);
0767:
0768: private String nameToEntryName(String name) {
0769: return archiveNameToEntryName(name + getExtension());
0770: }
0771:
0772: private String entryNameToName(String name) {
0773: String archiveName = entryNameToArchiveName(name);
0774:
0775: if (archiveName == null)
0776: return null;
0777: else
0778: return archiveName.substring(0, archiveName.length()
0779: - getExtension().length());
0780: }
0781:
0782: /**
0783: * returns a version's base name.
0784: */
0785: private String versionedNameToBaseName(String name) {
0786: int p = name.lastIndexOf('-');
0787: int ch;
0788:
0789: if (p > 0 && p + 1 < name.length()
0790: && '0' <= (ch = name.charAt(p + 1)) && ch <= '9')
0791: return name.substring(0, p);
0792: else
0793: return name;
0794: }
0795:
0796: public String[] getNames() {
0797: String[] names = new String[_controllerNames.size()];
0798:
0799: int i = 0;
0800:
0801: for (String controllerName : _controllerNames) {
0802: names[i++] = entryNameToName(controllerName);
0803: }
0804:
0805: return names;
0806: }
0807:
0808: private String getNamesAsString() {
0809: StringBuilder builder = new StringBuilder();
0810:
0811: for (String name : getNames()) {
0812: if (builder.length() > 0)
0813: builder.append(", ");
0814:
0815: builder.append(name);
0816: }
0817:
0818: builder.insert(0, '[');
0819: builder.append(']');
0820:
0821: return builder.toString();
0822: }
0823:
0824: /**
0825: * Start the archive.
0826: */
0827: public boolean start(String name) {
0828: DeployController controller = getDeployContainer()
0829: .findController(nameToEntryName(name));
0830:
0831: if (controller == null) {
0832: if (log.isLoggable(Level.FINE))
0833: log.log(Level.FINE, L.l(
0834: "{0} unknown name '{1}' in start", this , name));
0835:
0836: if (log.isLoggable(Level.FINER))
0837: log.log(Level.FINER, L.l(
0838: "{0} known names are {1} in start", this ,
0839: getNamesAsString()));
0840:
0841: return false;
0842: }
0843:
0844: controller.start();
0845:
0846: return true;
0847: }
0848:
0849: /**
0850: * Returns an exception for the named archive or null if there is no exception
0851: */
0852: public Throwable getConfigException(String name) {
0853: DeployController controller = getDeployContainer()
0854: .findController(nameToEntryName(name));
0855:
0856: if (controller == null) {
0857: if (log.isLoggable(Level.FINE))
0858: log.log(Level.FINE, L.l("unknown name '{0}'", name));
0859:
0860: if (log.isLoggable(Level.FINER))
0861: log.log(Level.FINER, L.l("known names are {0}",
0862: getNamesAsString()));
0863:
0864: return new ConfigException(L.l("unknown name '{0}'", name));
0865: }
0866:
0867: return controller.getConfigException();
0868: }
0869:
0870: /**
0871: * Stop the archive.
0872: */
0873: public boolean stop(String name) {
0874: DeployController controller = getDeployContainer()
0875: .findController(nameToEntryName(name));
0876:
0877: if (controller == null) {
0878: if (log.isLoggable(Level.FINE))
0879: log.log(Level.FINE, L.l("unknown name '{0}'", name));
0880:
0881: if (log.isLoggable(Level.FINER))
0882: log.log(Level.FINER, L.l("known names are {0}",
0883: getNamesAsString()));
0884:
0885: return false;
0886: }
0887:
0888: controller.stop();
0889: return true;
0890: }
0891:
0892: /**
0893: * Undeploy the archive.
0894: */
0895: public boolean undeploy(String name) {
0896: DeployController controller = getDeployContainer()
0897: .findController(nameToEntryName(name));
0898:
0899: if (controller == null) {
0900: if (log.isLoggable(Level.FINE))
0901: log.log(Level.FINE, L.l("unknown name '{0}'", name));
0902:
0903: if (log.isLoggable(Level.FINER))
0904: log.log(Level.FINER, L.l("known names are {0}",
0905: getNamesAsString()));
0906:
0907: return false;
0908: }
0909:
0910: Path archivePath = getArchivePath(name);
0911: Path expandPath = getExpandPath(name);
0912:
0913: controller.stop();
0914:
0915: try {
0916: if (log.isLoggable(Level.FINEST))
0917: log.log(Level.FINEST, L.l("deleting {0}", archivePath));
0918:
0919: archivePath.removeAll();
0920: } catch (IOException ex) {
0921: if (log.isLoggable(Level.FINE))
0922: log.log(Level.FINE, ex.toString(), ex);
0923: }
0924:
0925: try {
0926: if (expandPath != null) {
0927: if (log.isLoggable(Level.FINEST))
0928: log.log(Level.FINEST, L.l("deleting {0}",
0929: expandPath));
0930:
0931: expandPath.removeAll();
0932: }
0933: } catch (IOException ex) {
0934: if (log.isLoggable(Level.FINE))
0935: log.log(Level.FINE, ex.toString(), ex);
0936: }
0937:
0938: getDeployContainer().update(nameToEntryName(name));
0939:
0940: return true;
0941: }
0942:
0943: /**
0944: * Checks for updates.
0945: */
0946: public void handleAlarm(Alarm alarm) {
0947: if (isDestroyed())
0948: return;
0949:
0950: try {
0951: // XXX: tck, but no QA test
0952:
0953: // server/10ka
0954: if ("automatic".equals(getRedeployMode()) && isActive())
0955: request();
0956: } catch (Exception e) {
0957: log.log(Level.WARNING, e.toString(), e);
0958: } finally {
0959: _alarm.queue(_cronInterval);
0960: }
0961: }
0962:
0963: /**
0964: * Stops the deploy.
0965: */
0966: @Override
0967: protected void stopImpl() {
0968: _alarm.dequeue();
0969:
0970: super .stopImpl();
0971: }
0972:
0973: /**
0974: * Tests for equality.
0975: */
0976: public boolean equals(Object o) {
0977: if (o == null || !getClass().equals(o.getClass()))
0978: return false;
0979:
0980: ExpandDeployGenerator deploy = (ExpandDeployGenerator) o;
0981:
0982: Path expandDirectory = getExpandDirectory();
0983: Path deployExpandDirectory = deploy.getExpandDirectory();
0984:
0985: if (expandDirectory != deployExpandDirectory
0986: && (expandDirectory == null || !expandDirectory
0987: .equals(deployExpandDirectory)))
0988: return false;
0989:
0990: return true;
0991: }
0992:
0993: public String toString() {
0994: String name = getClass().getName();
0995: int p = name.lastIndexOf('.');
0996: if (p > 0)
0997: name = name.substring(p + 1);
0998:
0999: return name + "[" + getExpandDirectory() + "]";
1000: }
1001:
1002: }
|