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;
023:
024: import java.io.InputStream;
025: import java.io.UnsupportedEncodingException;
026: import java.net.URL;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029:
030: import javax.xml.parsers.DocumentBuilder;
031: import javax.xml.parsers.DocumentBuilderFactory;
032:
033: import org.jboss.system.server.ServerConfig;
034: import org.jboss.util.StringPropertyReplacer;
035: import org.w3c.dom.Element;
036: import org.w3c.dom.Node;
037: import org.w3c.dom.NodeList;
038: import org.xml.sax.InputSource;
039:
040: /**
041: * Static helper methods for NetBoot features
042: *
043: * @see org.jboss.deployment.NetBootFile
044: * @see org.jboss.deployment.SARDeployer
045: * @see org.jboss.deployment.scanner.HttpURLDeploymentScanner
046: *
047: * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
048: * @version $Revision: 57205 $
049: *
050: * <p><b>Revisions:</b>
051: *
052: * <p><b>7 novembre 2002 Sacha Labourey:</b>
053: * <ul>
054: * <li> First implementation </li>
055: * </ul>
056: */
057:
058: public class NetBootHelper {
059:
060: // Constants -----------------------------------------------------
061:
062: public final static String DEFAULT_NETBOOT_LISTING_URL = "jboss.netboot.listing.url";
063:
064: // Attributes ----------------------------------------------------
065:
066: // Static --------------------------------------------------------
067:
068: protected static org.jboss.logging.Logger log = org.jboss.logging.Logger
069: .getLogger(NetBootHelper.class);
070: protected static boolean traceEnabled = log.isTraceEnabled();
071:
072: // Constructors --------------------------------------------------
073:
074: // Public --------------------------------------------------------
075:
076: public static String buildDownloadUrlForFile(String baseUrl,
077: String directory, String filename) {
078: String part = baseUrl;
079: if (part.charAt(part.length() - 1) != '/')
080: part = part + "/";
081:
082: part = part + directory;
083: if (part.charAt(part.length() - 1) != '/')
084: part = part + "/";
085:
086: part = part + filename;
087:
088: return part;
089: }
090:
091: public static String getDefaultDownloadUrl() {
092: return System.getProperty(ServerConfig.SERVER_HOME_URL);
093: }
094:
095: public static String getDefaultListUrl()
096: throws IllegalStateException {
097: String defaultUrl = System
098: .getProperty(NetBootHelper.DEFAULT_NETBOOT_LISTING_URL);
099: if (defaultUrl == null) {
100: // No default listing URL is provided!
101: // We have a defaulting mode that can be used: if, on the server side,
102: // the JBossWeb NetBoot war is used, we can automatically use it
103: // The jboss.netboot.use.jbossweb System property can be set to false to
104: // disable this automatic behaviour
105: //
106: String autofallback = System
107: .getProperty("jboss.netboot.use.jbossweb");
108: if (autofallback == null
109: || !autofallback.equalsIgnoreCase("false")) {
110: if (traceEnabled)
111: log
112: .trace("jboss.netboot.use.jbossweb not defined but fallback activated...");
113: defaultUrl = System.getProperty(ServerConfig.HOME_URL);
114: int cropSize = defaultUrl.length();
115: if (defaultUrl.endsWith("/files"))
116: cropSize -= "/files".length() - 1;
117: else if (defaultUrl.endsWith("/files/"))
118: cropSize -= "/files/".length() - 1;
119: else
120: throw new IllegalStateException(
121: "No wildcard permitted in non-file URL deployment when jboss.netboot.listing.url not defined. "
122: + "You must either use the JBossWeb NetBoot WAR extension, specify individual jars"
123: + ", use the URL:* notation or specify the jboss.netboot.listing.url system property");
124: defaultUrl = System.getProperty(ServerConfig.HOME_URL)
125: .substring(0, cropSize)
126: + "List?";
127:
128: if (traceEnabled)
129: log.trace("...using: " + defaultUrl);
130: } else {
131: if (traceEnabled)
132: log
133: .trace("jboss.netboot.use.jbossweb not defined and fallback explicitly deactivated");
134: throw new IllegalStateException(
135: "No wildcard permitted in non-file URL deployment when jboss.netboot.listing.url not defined. "
136: + "You must either specify individual jars"
137: + ", use the URL:* notation or specify the jboss.netboot.listing.url system property");
138: }
139: }
140: return StringPropertyReplacer.replaceProperties(defaultUrl);
141: }
142:
143: public static String buildListUrlForFolder(String baseUrl,
144: String directory) throws IllegalStateException,
145: UnsupportedEncodingException {
146: String listUrl = null;
147:
148: if (baseUrl == null || "".equals(baseUrl)) {
149: // If not supplied, we provide the default URL
150: //
151: listUrl = getDefaultListUrl();
152: } else {
153: listUrl = baseUrl;
154: }
155:
156: return listUrl + "dir="
157: + java.net.URLEncoder.encode(directory, "UTF-8");
158: }
159:
160: public static NetBootFile[] listAllFromDirectory(String lister)
161: throws Exception {
162: return listAllFromDirectory(lister, true, true);
163: }
164:
165: public static NetBootFile[] listFilesFromDirectory(String lister)
166: throws Exception {
167: return listAllFromDirectory(lister, false, true);
168: }
169:
170: public static NetBootFile[] listDirectoriesFromDirectory(
171: String lister) throws Exception {
172: return listAllFromDirectory(lister, true, false);
173: }
174:
175: // Z implementation ----------------------------------------------
176:
177: // Y overrides ---------------------------------------------------
178:
179: // Package protected ---------------------------------------------
180:
181: // Protected -----------------------------------------------------
182:
183: /**
184: *
185: * The is expected document we should receive in result:
186: *
187: * <!ELEMENT directory (file*, sub-directory*)>
188: * <!ELEMENT file (name, modified, size)>
189: * <!ELEMENT sub-directory (name, modified)>
190: * <!ELEMENT name (#PCDATA)>
191: * <!ELEMENT modified (#PCDATA)>
192: * <!ELEMENT size (#PCDATA)>
193: *
194: * In this case we are only interested in file, not directories
195: *
196: */
197: protected static NetBootFile[] listAllFromDirectory(String lister,
198: boolean doDir, boolean doFiles) throws Exception {
199: if (traceEnabled)
200: log.trace("Getting directory listing from: " + lister);
201:
202: ArrayList result = new ArrayList();
203: // We now download the XML description from the remote URL
204: //
205: InputStream stream = new URL(lister).openStream();
206: InputSource is = new InputSource(stream);
207:
208: DocumentBuilder parser = DocumentBuilderFactory.newInstance()
209: .newDocumentBuilder();
210: org.w3c.dom.Document doc = parser.parse(is);
211:
212: if (doFiles) {
213: Iterator dirContentIter = getChildrenByTagName(doc
214: .getDocumentElement(), "file");
215: while (dirContentIter.hasNext()) {
216: Element item = (Element) dirContentIter.next();
217: String name = getUniqueChild(item, "name")
218: .getFirstChild().getNodeValue();
219: long lastModified = Long.parseLong(getUniqueChild(item,
220: "modified").getFirstChild().getNodeValue());
221: long size = Long.parseLong(getUniqueChild(item, "size")
222: .getFirstChild().getNodeValue());
223:
224: result.add(new NetBootFile(name, size, lastModified,
225: false, lister));
226: }
227: }
228:
229: if (doFiles) {
230: Iterator dirContentIter = getChildrenByTagName(doc
231: .getDocumentElement(), "directory");
232: while (dirContentIter.hasNext()) {
233: Element item = (Element) dirContentIter.next();
234: String name = getUniqueChild(item, "name")
235: .getFirstChild().getNodeValue();
236: long lastModified = Long.parseLong(getUniqueChild(item,
237: "modified").getFirstChild().getNodeValue());
238: long size = Long.parseLong(getUniqueChild(item, "size")
239: .getFirstChild().getNodeValue());
240:
241: result.add(new NetBootFile(name, size, lastModified,
242: true, lister));
243: }
244: }
245:
246: return (NetBootFile[]) result.toArray(new NetBootFile[] {});
247: }
248:
249: /**
250: * from org.jboss.metadata.MetaData which is not in the System module
251: * (which is understandable)
252: */
253: protected static Element getUniqueChild(Element element,
254: String tagName) throws DeploymentException {
255: Iterator goodChildren = getChildrenByTagName(element, tagName);
256:
257: if (goodChildren != null && goodChildren.hasNext()) {
258: Element child = (Element) goodChildren.next();
259: if (goodChildren.hasNext()) {
260: throw new DeploymentException("expected only one "
261: + tagName + " tag");
262: }
263: return child;
264: } else {
265: throw new DeploymentException("expected one " + tagName
266: + " tag");
267: }
268: }
269:
270: protected static Iterator getChildrenByTagName(Element element,
271: String tagName) {
272: if (element == null)
273: return null;
274: // getElementsByTagName gives the corresponding elements in the whole
275: // descendance. We want only children
276:
277: NodeList children = element.getChildNodes();
278: ArrayList goodChildren = new ArrayList();
279: for (int i = 0; i < children.getLength(); i++) {
280: Node currentChild = children.item(i);
281: if (currentChild.getNodeType() == Node.ELEMENT_NODE
282: && ((Element) currentChild).getTagName().equals(
283: tagName)) {
284: goodChildren.add((Element) currentChild);
285: }
286: }
287: return goodChildren.iterator();
288: }
289:
290: // Private -------------------------------------------------------
291:
292: // Inner classes -------------------------------------------------
293:
294: }
|