/* * HJB4U is toolchain for creating a HyperJAXB front end for database users. * Copyright (C) 2010 NigelB * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package hjb4u; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; import hjb4u.config.hjb4u.Constants; import hjb4u.config.hjb4u.DBList; import hjb4u.config.hjb4u.HJB4UConfiguration; import hjb4u.config.hjb4u.NameSpaceMapping; import hjb4u.exceptions.NamespaceException; import hjb4u.gui.ListClass; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.*; import java.lang.annotation.Annotation; import java.net.URL; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import static hjb4u.Util.joinPath; /** * <code>SettingsStore</code> * Date: 07/07/2009 * Time: 6:15:36 PM * * @author Nigel B */ public class SettingsStore { private HJB4UConfiguration settings; private static SettingsStore instance; private String conf_dir; private File store; private JAXBContext context = JAXBContext.newInstance(HJB4UConfiguration.class); private Unmarshaller unmar = context.createUnmarshaller(); private Marshaller mar = context.createMarshaller(); private Logger logger = Logger.getLogger(SettingsStore.class); private DBList templates; private String episode = "META-INF/sun-jaxb.episode"; public static void instanciate(String conf_dir, String settings) throws JAXBException { instance = new SettingsStore(conf_dir, new File(conf_dir + File.separator + settings)); } private SettingsStore(String conf_dir, File store) throws JAXBException { this.conf_dir = conf_dir; this.store = store; try { mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); settings = (HJB4UConfiguration) unmar.unmarshal(store); } catch (JAXBException e) { if (e.getLinkedException() instanceof FileNotFoundException) { logger.debug("Settings Not Found."); settings = new HJB4UConfiguration(); settings.setNamespaces(makeDefaultNamespaces()); }else { throw e; } }catch(NamespaceException npe) { logger.error("Namespace Mappings have been curropted."); logger.info("Using default Namespace Mappings."); NameSpaceMapping.__ignore = true; settings = (HJB4UConfiguration) unmar.unmarshal(store); NameSpaceMapping.__ignore = false; settings.setNamespaces(makeDefaultNamespaces()); try { save(); } catch (FileNotFoundException e) { logger.error("Could not revert namespaces."); } } } public List<NameSpaceMapping> makeDefaultNamespaces() { ArrayList<NameSpaceMapping> toRet = new ArrayList<NameSpaceMapping>(); try { URL nsmap = this.getClass().getClassLoader().getResource(episode); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(nsmap.openStream()); Element root = doc.getDocumentElement(); NodeList nl = root.getChildNodes(); Node n; Element e; int nscount = 1; NameSpaceMapping nsm; for (int i = nl.getLength(); i >= 0; i--) { n = nl.item(i); if (n instanceof Element) { e = (Element) n; toRet.add(nsm = new NameSpaceMapping(e.getAttribute("xmlns:tns"), "ns" + nscount++)); logger.debug(new StringBuilder().append(nsm.getPrefix()).append(": ").append(nsm.getNamespace()).toString()); } } } catch (Exception e) { logger.debug(e, e); return toRet; } return toRet; } public List<ListClass> makeRootElementList() { ArrayList<ListClass> toRet = new ArrayList<ListClass>(); try { Class[] cls = ClassFinder.getEpisodeClasses(this.getClass().getClassLoader().getResource(episode)); Annotation ant; for (Class cl : cls) { ant = cl.getAnnotation(XmlRootElement.class); if(ant != null) { toRet.add(new ListClass(cl)); } } } catch (IOException e) { logger.error(e, e); } return toRet; } public Class[] getAllJAXBClasses() { Class[] cls = new Class[]{}; try { cls = ClassFinder.findAllJAXBClasses(this.getClass().getClassLoader().getResource(episode)); } catch (IOException e) { logger.error(e, e); } return cls; } public void save() throws JAXBException, FileNotFoundException { OutputStream os; mar.marshal(settings, os = new BufferedOutputStream(new FileOutputStream(store))); try { os.flush(); os.close(); } catch (IOException e) { logger.error(e, e); } } public static SettingsStore getInstance() { return instance; } public HJB4UConfiguration getSettings() { return settings; } public File getStoreLocation() { return store; } public String getStorePath() { try { return store.getAbsoluteFile().getCanonicalPath(); } catch (IOException e) { logger.error(e, e); } return store.getPath(); } public String getConfDir() { return conf_dir; } public String getXSLTDir() { return joinPath(getConfDir(), Constants.XSLT_DIR_PATH); } public NamespacePrefixMapper getNamespaceMapper() { Hashtable<String, String> map = new Hashtable<String, String>(); boolean has_default = false; for (int i = 0; i < settings.getNamespaces().size(); i++) { NameSpaceMapping ns = settings.getNamespaces().get(i); if (ns.isDefault()) { if (has_default) { logger.error(String.format("There is already a default Namespace, so %s cannot be it. Reverting to default Namespace Map.", ns.getNamespace())); settings.setNamespaces(makeDefaultNamespaces()); return getNamespaceMapper(); } map.put(ns.getNamespace(), HJB4UNameSpaceMapper.DEFAULT); has_default = true; } else { map.put(ns.getNamespace(), ns.getPrefix()); } } return new HJB4UNameSpaceMapper(map); } public void setDatabaseTemplates(DBList templates) { this.templates = templates; } public DBList getTemplates() { return templates; } public String getEpisode() { return episode; } public void setEpisode(String episode) { this.episode = episode; } }