Java tutorial
/* * Copyright (c) 2008-2016 Haulmont. * * 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 com.haulmont.cuba.core.sys.persistence; import com.haulmont.bali.util.Dom4j; import com.haulmont.bali.util.ReflectionHelper; import com.haulmont.cuba.core.global.Stores; import com.haulmont.cuba.core.sys.AppContext; import com.haulmont.cuba.core.sys.ConfigurationResourceLoader; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import javax.persistence.Entity; import java.io.*; import java.util.*; /** * Generates a working persistence.xml file combining classes and properties from a set of given persistence.xml files, * defined in <code>cuba.persistenceConfig</code> app property. * */ public class PersistenceConfigProcessor { private String baseDir; private List<String> sourceFileNames; private String outFileName; private String storeName; private static final Logger log = LoggerFactory.getLogger(PersistenceConfigProcessor.class); public void setBaseDir(String baseDir) { this.baseDir = baseDir; } public void setSourceFiles(List<String> files) { sourceFileNames = files; } public void setOutputFile(String file) { outFileName = file; } public void setStorageName(String storeName) { this.storeName = storeName; } public void create() { if (sourceFileNames == null || sourceFileNames.isEmpty()) throw new IllegalStateException("Source file list not set"); if (StringUtils.isBlank(outFileName)) throw new IllegalStateException("Output file not set"); Map<String, String> classes = new LinkedHashMap<>(); Map<String, String> properties = new HashMap<>(); properties.putAll(DbmsSpecificFactory.getDbmsFeatures(storeName).getJpaParameters()); for (String fileName : sourceFileNames) { Document doc = getDocument(fileName); Element puElem = findPersistenceUnitElement(doc.getRootElement()); if (puElem == null) throw new IllegalStateException( "No persistence unit named 'cuba' found among multiple units inside " + fileName); addClasses(puElem, classes); addProperties(puElem, properties); } for (String name : AppContext.getPropertyNames()) { if (name.startsWith("eclipselink.")) { properties.put(name, AppContext.getProperty(name)); } } if (!Stores.isMain(storeName)) properties.put(PersistenceImplSupport.PROP_NAME, storeName); File outFile; try { outFile = new File(outFileName).getCanonicalFile(); } catch (IOException e) { throw new RuntimeException(e); } outFile.getParentFile().mkdirs(); boolean ormXmlCreated = true; String disableOrmGenProp = AppContext.getProperty("cuba.disableOrmXmlGeneration"); if (!Boolean.parseBoolean(disableOrmGenProp)) { MappingFileCreator mappingFileCreator = new MappingFileCreator(classes.values(), properties, outFile.getParentFile()); ormXmlCreated = mappingFileCreator.create(); } String fileName = sourceFileNames.get(sourceFileNames.size() - 1); Document doc = getDocument(fileName); Element rootElem = doc.getRootElement(); Element puElem = findPersistenceUnitElement(rootElem); if (puElem == null) throw new IllegalStateException( "No persistence unit named 'cuba' found among multiple units inside " + fileName); String puName = AppContext.getProperty("cuba.persistenceUnitName"); if (!StringUtils.isEmpty(puName)) { if (!Stores.isMain(storeName)) puName = puName + "_" + storeName; puElem.addAttribute("name", puName); } for (Element element : new ArrayList<>(Dom4j.elements(puElem, "class"))) { puElem.remove(element); } puElem.addElement("provider").setText("org.eclipse.persistence.jpa.PersistenceProvider"); if (ormXmlCreated) { puElem.addElement("mapping-file").setText("orm.xml"); } for (String className : classes.values()) { puElem.addElement("class").setText(className); } puElem.addElement("exclude-unlisted-classes"); Element propertiesEl = puElem.element("properties"); if (propertiesEl != null) puElem.remove(propertiesEl); propertiesEl = puElem.addElement("properties"); for (Map.Entry<String, String> entry : properties.entrySet()) { Element element = propertiesEl.addElement("property"); element.addAttribute("name", entry.getKey()); element.addAttribute("value", entry.getValue()); } log.info("Creating file " + outFile); OutputStream os = null; try { os = new FileOutputStream(outFileName); Dom4j.writeDocument(doc, true, os); } catch (IOException e) { throw new RuntimeException(e); } finally { IOUtils.closeQuietly(os); } } private void addClasses(Element puElem, Map<String, String> classes) { for (Element element : Dom4j.elements(puElem, "class")) { String className = element.getText(); Class<Object> cls = ReflectionHelper.getClass(className); Entity annotation = cls.getAnnotation(Entity.class); if (annotation != null) { classes.put(annotation.name(), className); } else { classes.put(className, className); } } } private void addProperties(Element puElem, Map<String, String> properties) { Element propertiesEl = puElem.element("properties"); if (propertiesEl != null) { for (Element element : Dom4j.elements(propertiesEl, "property")) { properties.put(element.attributeValue("name"), element.attributeValue("value")); } } } private Element findPersistenceUnitElement(Element rootElem) { List<Element> puList = Dom4j.elements(rootElem, "persistence-unit"); if (puList.size() == 1) { return puList.get(0); } else { for (Element element : puList) { if ("cuba".equals(element.attributeValue("name"))) { return element; } } } return null; } private Document getDocument(String fileName) { Document doc; if (baseDir == null) { Resource resource = new ConfigurationResourceLoader().getResource(fileName); InputStream stream = null; try { stream = resource.getInputStream(); doc = Dom4j.readDocument(stream); } catch (IOException e) { throw new RuntimeException(e); } finally { IOUtils.closeQuietly(stream); } } else { if (!fileName.startsWith("/")) fileName = "/" + fileName; File file = new File(baseDir, fileName); if (!file.exists()) throw new IllegalArgumentException("File not found: " + file.getAbsolutePath()); doc = Dom4j.readDocument(file); } return doc; } }