| /* |
| * $Id$ |
| * |
| * Copyright 2006 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.struts2.quickstart; |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| |
| import org.apache.commons.collections.MultiHashMap; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| import com.thoughtworks.xstream.XStream; |
| |
| /** |
| * Configuration for the QuickStart program. |
| */ |
| public class Configuration implements Serializable { |
| |
| private static final long serialVersionUID = 9159115401614443449L; |
| |
| String ideaConfig; |
| String extendsConfig; |
| String resolver; |
| Integer port; |
| String context; |
| List libs; |
| List classDirs; |
| List sources; |
| List webDirs; |
| Map mappings; |
| List pathPriority; |
| |
| public String getIdeaConfig() { |
| return ideaConfig; |
| } |
| |
| public void setIdeaConfig(String ideaConfig) { |
| this.ideaConfig = ideaConfig; |
| } |
| |
| public String getExtendsConfig() { |
| return extendsConfig; |
| } |
| |
| public void setExtendsConfig(String extendsConfig) { |
| this.extendsConfig = extendsConfig; |
| } |
| |
| public String getResolver() { |
| return resolver; |
| } |
| |
| public void setResolver(String resolver) { |
| this.resolver = resolver; |
| } |
| |
| public List getLibs() { |
| return libs; |
| } |
| |
| public void setLibs(List libs) { |
| this.libs = libs; |
| } |
| |
| public List getClassDirs() { |
| return classDirs; |
| } |
| |
| public void setClassDirs(List classDirs) { |
| this.classDirs = classDirs; |
| } |
| |
| public List getSources() { |
| return sources; |
| } |
| |
| public void setSources(List sources) { |
| this.sources = sources; |
| } |
| |
| public Map getMappings() { |
| return mappings; |
| } |
| |
| public List getPathPriority() { |
| return pathPriority; |
| } |
| |
| public List getWebDirs() { |
| return webDirs; |
| } |
| |
| public void setWebDirs(List webDirs) { |
| this.webDirs = webDirs; |
| } |
| |
| public Integer getPort() { |
| return port; |
| } |
| |
| public void setPort(Integer port) { |
| this.port = port; |
| } |
| |
| public String getContext() { |
| return context; |
| } |
| |
| public void setContext(String context) { |
| this.context = context; |
| } |
| |
| public void resolveDirs(String wd) { |
| if (ideaConfig != null) { |
| String[] paths = ideaConfig.split(","); |
| for (String path : paths) { |
| String full = resolveDir(path, wd); |
| |
| try { |
| DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); |
| Document doc = db.parse(full); |
| NodeList components = doc.getElementsByTagName("root"); |
| List jars = new ArrayList(); |
| for (int i = 0; i < components.getLength(); i++) { |
| Element e = (Element) components.item(i); |
| String value = e.getAttribute("url"); |
| if (value != null && value.startsWith("jar://") && value.endsWith(".jar!/")) { |
| value = value.substring(6, value.length() - 2); |
| if (value.startsWith("$MODULE_DIR$")) { |
| value = value.substring(13); |
| } |
| jars.add(value); |
| } |
| } |
| |
| if (this.libs != null) { |
| this.libs.addAll(jars); |
| } else { |
| this.libs = jars; |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| resolve(this.libs, wd); |
| resolve(this.classDirs, wd); |
| resolve(this.sources, wd); |
| |
| // now resolve the web dirs |
| for (Iterator iterator = webDirs.iterator(); iterator.hasNext();) { |
| Mapping mapping = (Mapping) iterator.next(); |
| String path = mapping.getPath(); |
| String dir = mapping.getDir(); |
| dir = resolveDir(dir, wd); |
| |
| // if the ${dir}/WEB-INF/classes dir exists and isn't already added to the classDirs, let's do it |
| // ... but make sure we put it at the front (to obey the class loading behaviors) |
| File classDir = new File(dir, "WEB-INF/classes"); |
| if (classDir.exists()) { |
| String fullClassDir = getFullPath(classDir); |
| if (this.classDirs == null) { |
| this.classDirs = new ArrayList(); |
| } |
| |
| if (!classDirs.contains(fullClassDir)) { |
| classDirs.add(0, fullClassDir); |
| } |
| } |
| |
| if (this.mappings == null) { |
| this.mappings = new MultiHashMap(); |
| this.pathPriority = new ArrayList(); |
| } |
| |
| if (!this.pathPriority.contains(path)) { |
| this.pathPriority.add(path); |
| } |
| this.mappings.put(path, dir); |
| } |
| } |
| |
| private void resolve(List list, String wd) { |
| if (list != null) { |
| for (int i = 0; i < list.size(); i++) { |
| String s = (String) list.get(i); |
| list.set(i, resolveDir(s, wd)); |
| } |
| } |
| } |
| |
| private String resolveDir(String dir, String wd) { |
| File file = new File(wd, dir); |
| if (!file.exists() && new File(dir).exists()) { |
| file = new File(dir); |
| } |
| |
| return getFullPath(file); |
| } |
| |
| private String getFullPath(File file) { |
| try { |
| return file.getCanonicalPath(); |
| } catch (IOException e) { |
| return file.getAbsolutePath(); |
| } |
| } |
| |
| public void resolveExtensions(String wd, XStream xstream) throws FileNotFoundException { |
| if (extendsConfig != null) { |
| File config = new File(wd, extendsConfig); |
| Configuration c = (Configuration) xstream.fromXML(new FileReader(config)); |
| c.resolveDirs(config.getParent()); |
| c.resolveExtensions(config.getParent(), xstream); |
| |
| // now copy over the props |
| if (c.getResolver() != null) { |
| this.resolver = c.getResolver(); |
| } |
| |
| if (port == null) { |
| this.port = c.getPort(); |
| } |
| |
| if (c.getContext() != null) { |
| this.context = c.getContext(); |
| } |
| |
| if (c.getLibs() != null) { |
| if (this.libs != null) { |
| this.libs.addAll(c.getLibs()); |
| } else { |
| this.libs = c.getLibs(); |
| } |
| } |
| |
| if (c.getClassDirs() != null) { |
| if (this.classDirs != null) { |
| this.classDirs.addAll(c.getClassDirs()); |
| } else { |
| this.classDirs = c.getClassDirs(); |
| } |
| } |
| |
| if (c.getSources() != null) { |
| if (this.sources != null) { |
| this.sources.addAll(c.getSources()); |
| } else { |
| this.sources = c.getSources(); |
| } |
| } |
| |
| for (Iterator iterator = c.getMappings().entrySet().iterator(); iterator.hasNext();) { |
| Map.Entry entry = (Map.Entry) iterator.next(); |
| List list = (List) this.mappings.get(entry.getKey()); |
| if (list != null) { |
| list.addAll((List) entry.getValue()); |
| } else { |
| this.mappings.put(entry.getKey(), (List) entry.getValue()); |
| } |
| } |
| |
| // add only new paths |
| for (Iterator iterator = c.getPathPriority().iterator(); iterator.hasNext();) { |
| String path = (String) iterator.next(); |
| if (!this.pathPriority.contains(path)) { |
| this.pathPriority.add(path); |
| } |
| } |
| } |
| } |
| |
| public boolean validate() { |
| boolean error = false; |
| |
| if (port == null) { |
| System.out.println("Port must be greater than 0"); |
| error = true; |
| } |
| |
| if (!context.startsWith("/")) { |
| System.out.println("Context must start with /"); |
| error = true; |
| } |
| |
| |
| if (verifyList("Library", libs, false)) { |
| error = true; |
| } |
| |
| if (verifyList("ClassDir", classDirs, false)) { |
| error = true; |
| } |
| |
| if (verifyList("Sources", sources, true)) { |
| error = true; |
| } |
| |
| if (verifyMap("WebApp", mappings)) { |
| error = true; |
| } |
| |
| return error; |
| } |
| |
| private boolean verifyMap(String name, Map map) { |
| boolean error = false; |
| if (map == null || map.size() == 0) { |
| System.out.println(name + " must be specified"); |
| return true; |
| } |
| |
| for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { |
| Map.Entry entry = (Map.Entry) iterator.next(); |
| List list = (List) entry.getValue(); |
| verifyList(name, list, false); |
| } |
| |
| return error; |
| } |
| |
| private boolean verifyList(String name, List list, boolean allowEmpty) { |
| boolean error = false; |
| if (!allowEmpty) { |
| if (list == null || list.size() == 0) { |
| System.out.println(name + " must be specified"); |
| return true; |
| } |
| } |
| |
| if (list != null) { |
| for (Iterator iterator = list.iterator(); iterator.hasNext();) { |
| String s = (String) iterator.next(); |
| if (!new File(s).exists()) { |
| System.out.println(name + " doesn't exist: " + s); |
| error = true; |
| } |
| } |
| } |
| |
| return error; |
| } |
| } |