001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library 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 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.configuration; 029 030import java.io.File; 031 032import javax.xml.parsers.DocumentBuilder; 033import javax.xml.parsers.DocumentBuilderFactory; 034import javax.xml.transform.Transformer; 035import javax.xml.transform.TransformerFactory; 036import javax.xml.transform.dom.DOMSource; 037import javax.xml.transform.stream.StreamResult; 038 039import org.w3c.dom.Document; 040import org.w3c.dom.Element; 041import org.w3c.dom.NodeList; 042 043/** 044 * Persistence configuration class.<p> 045 * 046 * This class allow to be managed (reading and writing) JPA persistence.xml configuration file.<p> 047 * 048 * @since 8.0.0 049 */ 050public class CmsPersistenceUnitConfiguration { 051 052 /** Attribute name for connection settings for Apache OpenJPA & DBCP. */ 053 public static final String ATTR_CONNECTION_PROPERTIES = "openjpa.ConnectionProperties"; 054 055 /** Attribute name for connection settings. */ 056 public static final String ATTR_GENERATE_SCHEMA = "openjpa.jdbc.SynchronizeMappings"; 057 058 /** Attribute name for connection settings. */ 059 public static final String ATTR_GENERATE_SCHEMA_VALUE = "buildSchema(ForeignKeys=true)"; 060 061 /** Attribute name for attribute "name" of property. */ 062 public static final String ATTR_NAME = "name"; 063 064 /** Attribute name for attribute "value" of property. */ 065 public static final String ATTR_VALUE = "value"; 066 067 /** Tag constant. */ 068 public static final String TAG_PERSISTENCE_UNIT = "persistence-unit"; 069 070 /** Tag constant. */ 071 public static final String TAG_PROPERTIES = "properties"; 072 073 /** Tag constant. */ 074 public static final String TAG_PROPERTY = "property"; 075 076 /** DOM document. */ 077 private Document m_document; 078 079 /** Configuration file name (usually it's persistence.xml file. */ 080 private String m_fileName; 081 082 /** DOM element represents persistence node/element. */ 083 private Element m_persistenceUnit; 084 085 /** Persistence unit name to be configured. */ 086 private String m_persistenceUnitName; 087 088 /** List of nodes/elements with specific configuration parameters for particular JPA implementation. */ 089 private NodeList m_properties; 090 091 /** Property element. */ 092 private Element m_propertiesElement; 093 094 /** 095 * Public constructor which initialize the object.<p> 096 * 097 * @param unitName persistence unit name to be managed 098 * @param fileName configuration file name 099 */ 100 public CmsPersistenceUnitConfiguration(String unitName, String fileName) { 101 102 m_fileName = new String(fileName); 103 m_persistenceUnitName = unitName; 104 m_document = readDocument(m_fileName); 105 m_persistenceUnit = getPersistenceUnit(m_document.getDocumentElement()); 106 m_propertiesElement = (Element)m_persistenceUnit.getElementsByTagName(TAG_PROPERTIES).item(0); 107 refreshProperties(); 108 } 109 110 /** 111 * Returns a property value for the given property name.<p> 112 * 113 * @param name the name of the property 114 * @param defaultValue the default value if there was no property configured with the given name 115 * 116 * @return a property value for the given property name 117 */ 118 public String getPropertyValue(String name, String defaultValue) { 119 120 Element el = null; 121 for (int i = 0; i < m_properties.getLength(); i++) { 122 el = (Element)m_properties.item(i); 123 if (name.equalsIgnoreCase(el.getAttribute(ATTR_NAME))) { 124 return el.getAttribute(ATTR_VALUE); 125 } 126 } 127 return defaultValue; 128 } 129 130 /** 131 * Removes property with given name.<p> 132 * 133 * @param name value of the name attribute 134 */ 135 public void removeProperty(String name) { 136 137 Element el = null; 138 for (int i = 0; i < m_properties.getLength(); i++) { 139 el = (Element)m_properties.item(i); 140 if (name.equalsIgnoreCase(el.getAttribute(ATTR_NAME))) { 141 m_propertiesElement.removeChild(el); 142 break; 143 } 144 } 145 refreshProperties(); 146 } 147 148 /** 149 * Saves the original configuration file.<p> 150 */ 151 public void save() { 152 153 save(m_fileName); 154 } 155 156 /** 157 * Sets property value with given name and value.<p> 158 * 159 * @param name value of the name attribute 160 * @param value value of the value attribute 161 */ 162 public void setPropertyValue(String name, String value) { 163 164 boolean exist = false; 165 166 Element el = null; 167 for (int i = 0; i < m_properties.getLength(); i++) { 168 el = (Element)m_properties.item(i); 169 if (name.equalsIgnoreCase(el.getAttribute(ATTR_NAME))) { 170 el.setAttribute(ATTR_VALUE, value); 171 exist = true; 172 break; 173 } 174 } 175 176 if (!exist) { 177 addProperty(name, value); 178 } 179 } 180 181 /** 182 * Adds a property.<p> 183 * 184 * @param name the name of the property 185 * @param value the value for the property 186 */ 187 private void addProperty(String name, String value) { 188 189 Element el = m_document.createElement(TAG_PROPERTY); 190 el.setAttribute(ATTR_NAME, name); 191 el.setAttribute(ATTR_VALUE, value); 192 m_propertiesElement.appendChild(el); 193 refreshProperties(); 194 } 195 196 /** 197 * Returns DOM element of persistence unit with name represents by m_persistenceUnitName.<p> 198 * 199 * @param e document element of xml document 200 * 201 * @return element for given name or null value if it does not exist 202 */ 203 private Element getPersistenceUnit(Element e) { 204 205 NodeList list = e.getElementsByTagName(TAG_PERSISTENCE_UNIT); 206 Element el = null; 207 for (int i = 0; i < list.getLength(); i++) { 208 el = (Element)list.item(i); 209 if (m_persistenceUnitName.equalsIgnoreCase(el.getAttribute(ATTR_NAME))) { 210 break; 211 } 212 } 213 return el; 214 } 215 216 /** 217 * Reads the configuration file.<p> 218 * 219 * @param fileName file name 220 * 221 * @return DOM model of configuration file 222 */ 223 private Document readDocument(String fileName) { 224 225 Document doc = null; 226 try { 227 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 228 File f = new File(fileName); 229 doc = builder.parse(f); 230 } catch (Exception e) { 231 e.printStackTrace(); 232 } 233 return doc; 234 } 235 236 /** 237 * Refreshes the list with all properties for particular persistence unit.<p> 238 */ 239 private void refreshProperties() { 240 241 m_properties = m_propertiesElement.getElementsByTagName(TAG_PROPERTY); 242 } 243 244 /** 245 * Save the configuration to file.<p> 246 * 247 * @param fileName the full path with file name to the persistence.xml 248 */ 249 private void save(String fileName) { 250 251 try { 252 Transformer transformer = TransformerFactory.newInstance().newTransformer(); 253 DOMSource source = new DOMSource(m_document); 254 File file = new File(fileName); 255 StreamResult result = new StreamResult(file); 256 transformer.transform(source, result); 257 } catch (Exception e) { 258 e.printStackTrace(); 259 } 260 } 261}