/* * JBoss, a division of Red Hat * Copyright 2006, Red Hat Middleware, LLC, and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.ide.eclipse.freemarker.configuration; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.JarEntryFile; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.swt.widgets.Shell; import org.jboss.ide.eclipse.freemarker.Plugin; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Joe Hudson */ public class ConfigurationManager { private static final Map instances = new HashMap(); private IProject project; private ProjectClassLoader projectClassLoader; private Map contextValues = new HashMap(); private Map macroLibrary = new HashMap(); private MacroLibrary[] macroLibraryArr; private ConfigurationManager () {} public synchronized static final ConfigurationManager getInstance (IProject project) { ConfigurationManager configuration = (ConfigurationManager) instances.get(project.getName()); if (null == configuration) { configuration = new ConfigurationManager(); configuration.project = project; configuration.reload(); instances.put(project.getName(), configuration); } return configuration; } public MacroLibrary[] getMacroLibraries () { return macroLibraryArr; } public void associateMappingLibraries (List libraries, Shell shell) { for (Iterator i=libraries.iterator(); i.hasNext(); ) { Object obj = i.next(); if (obj instanceof IFile) { IFile file = (IFile) obj; String namespace = file.getName(); int index = namespace.indexOf("."); if (index >= 0) namespace = namespace.substring(0, index); InputDialog inputDialog = new InputDialog( shell, "Choose Macro Library Namespace", "Please choose the namespace for '" + file.getName() + "'", namespace, null); int rtn = inputDialog.open(); if (rtn == IDialogConstants.OK_ID) { namespace = inputDialog.getValue(); try { this.macroLibrary.put(namespace, new MacroLibrary(namespace, file)); } catch (CoreException e) { Plugin.error(e); } catch (IOException e) { Plugin.error(e); } } } else if (obj instanceof JarEntryFile) { JarEntryFile jef = (JarEntryFile) obj; String namespace = jef.getName(); int index = namespace.indexOf("."); if (index >= 0) namespace = namespace.substring(0, index); InputDialog inputDialog = new InputDialog( shell, "Choose Macro Library Namespace", "Please choose the namespace for '" + jef.getName() + "'", namespace, null); int rtn = inputDialog.open(); if (rtn == IDialogConstants.OK_ID) { namespace = inputDialog.getValue(); try { InputStream is = getProjectClassLoader().getResourceAsStream(jef.getFullPath().toString()); if (null != is) { this.macroLibrary.put(namespace, new MacroLibrary(namespace, is, jef.getFullPath().toString(), MacroLibrary.TYPE_JAR_ENTRY)); } else { // FIXME: add error dialog here } } catch (CoreException e) { Plugin.error(e); } catch (IOException e) { Plugin.error(e); } } } } save(); } public MacroLibrary getMacroLibrary (String namespace) { return (MacroLibrary) macroLibrary.get(namespace); } private void writeMacroLibrary(StringBuffer sb) { for (Iterator i=macroLibrary.values().iterator(); i.hasNext(); ) { MacroLibrary macroLibrary = (MacroLibrary) i.next(); sb.append("\t\t" + macroLibrary.toXML() + "\n"); } } private Map loadMacroTemplates (Element element) { Map map = new HashMap(); try { NodeList nl = element .getElementsByTagName("entry"); for (int i = 0; i < nl.getLength(); i++) { try { Node n = nl.item(i); MacroLibrary macroLibrary = MacroLibrary.fromXML(project, (Element) n, getProjectClassLoader()); if (null != macroLibrary) { String namespace = macroLibrary.getNamespace(); if(map.get(namespace) != null) { for(int x =0; x0) singularClass = getClass(singularName); contextValues.add(new ContextValue(key, value, singularClass)); } map.put(path, contextValues .toArray(new ContextValue[contextValues .size()])); } catch (Exception e) { Plugin.log(e); } } } catch (Exception e) { Plugin.log(e); } return map; } public synchronized Class getClass(String className) throws JavaModelException, ClassNotFoundException { return getProjectClassLoader().loadClass(className); } public synchronized ClassLoader getProjectClassLoader() throws JavaModelException { if (null == this.projectClassLoader) this.projectClassLoader = new ProjectClassLoader(JavaCore.create(project)); return this.projectClassLoader; } private void save() { StringBuffer sb = new StringBuffer(); sb.append("\n"); sb.append("\t\n"); writeContextValues(sb); sb.append("\t\n"); sb.append("\t\n"); writeMacroLibrary(sb); sb.append("\t\n"); sb.append(""); IFile file = project.getFile(".freemarker-ide.xml"); try { if (file.exists()) file.setContents(new ByteArrayInputStream(sb.toString() .getBytes()), true, true, null); else file.create(new ByteArrayInputStream(sb.toString().getBytes()), true, null); } catch (Exception e) { Plugin.error(e); } reload(); } public void reload() { this.projectClassLoader = null; IFile file = project.getFile(".freemarker-ide.xml"); if (file.exists()) { try { file.refreshLocal(1, null); } catch (CoreException e) {} Map map = new HashMap(); try { Document document = DocumentBuilderFactory.newInstance() .newDocumentBuilder().parse(file.getContents()); NodeList nl = document.getDocumentElement() .getElementsByTagName("context-values"); if (nl.getLength() > 0) this.contextValues = loadContextValues((Element) nl.item(0)); else this.contextValues = new HashMap(); nl = document.getDocumentElement() .getElementsByTagName("macro-library"); List libraries = new ArrayList(); if (nl.getLength() > 0) { this.macroLibrary = loadMacroTemplates((Element) nl.item(0)); for (Iterator i=macroLibrary.values().iterator(); i.hasNext(); ) { libraries.add(i.next()); } } else this.macroLibrary = new HashMap(); macroLibraryArr = (MacroLibrary[]) libraries.toArray(new MacroLibrary[libraries.size()]); } catch (Exception e) { Plugin.error(e); } } } private void writeContextValues(StringBuffer sb) { for (Iterator i = contextValues.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String fileName = (String) entry.getKey(); ContextValue[] values = (ContextValue[]) entry.getValue(); if (null != values && values.length > 0) { sb.append("\t\t\n"); for (int j = 0; j < values.length; j++) { sb.append("\t\t\t\n"); } sb.append("\t\t\n"); } } } public ContextValue[] getContextValues(IResource resource, boolean recurse) { Map newValues = new HashMap(); addRootContextValues(resource, newValues, recurse); return (ContextValue[]) newValues.values().toArray(new ContextValue[newValues.size()]); } private void addRootContextValues(IResource resource, Map newValues, boolean recurse) { String key = null; if (null != resource.getParent()) { key = resource.getProjectRelativePath().toString(); if (recurse) addRootContextValues(resource.getParent(), newValues, true); } else key = ""; if (null != resource.getProject()) { ContextValue[] values = (ContextValue[]) contextValues.get(key); if (null != values) { for (int i=0; i= 0) { ContextValue[] newValues = new ContextValue[values.length - 1]; int j = 0; for (int i = 0; i < values.length; i++) { if (i != index) newValues[j++] = values[i]; } this.contextValues.put(resource.getProjectRelativePath().toString(), newValues); save(); } } }