/* * gvNIX is an open source tool for rapid application development (RAD). * Copyright (C) 2010 Generalitat Valenciana * * 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 3 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, see <http://www.gnu.org/licenses/>. */ package org.gvnix.addon.jpa.addon.geo.providers.hibernatespatial; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.springframework.roo.model.JavaPackage; import org.springframework.roo.process.manager.FileManager; import org.springframework.roo.process.manager.MutableFile; import org.springframework.roo.project.Dependency; import org.springframework.roo.project.LogicalPath; import org.springframework.roo.project.Path; import org.springframework.roo.project.PathResolver; import org.springframework.roo.project.ProjectOperations; import org.springframework.roo.project.Repository; import org.springframework.roo.support.util.DomUtils; import org.springframework.roo.support.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author <a href="http://www.disid.com">DISID Corporation S.L.</a> made for <a * href="http://www.dgti.gva.es">General Directorate for Information * Technologies (DGTI)</a> */ public class HibernateSpatialGeoUtils { /** * This method checks if persistence is setup and if HIBERNATE was selected * as provider persistence * * @param fileManager * @param pathResolver * @return */ public static boolean isHibernateProviderPersistence( FileManager fileManager, PathResolver pathResolver) { // persistence.xml file final String persistenceFile = pathResolver.getFocusedIdentifier( Path.SRC_MAIN_RESOURCES, "META-INF/persistence.xml"); // if persistence.xml doesn't exists, return false if (fileManager.exists(persistenceFile)) { // Getting document final Document persistenceXmlDocument = XmlUtils .readXml(fileManager.getInputStream(persistenceFile)); final Element persistenceElement = persistenceXmlDocument .getDocumentElement(); // Getting provider tag final Element provider = DomUtils.findFirstElementByName( "provider", persistenceElement); // Checking if provider is not null Validate.notNull(provider, "Could not find provider in %s", persistenceElement); NodeList node = provider.getChildNodes(); // Getting providerValue String providerValue = node.item(0).getNodeValue(); // If provider selected is HIBERNATE returns true if (providerValue.startsWith("org.hibernate")) { return true; } return false; } else { return false; } } /** * * This method update repositories with the added to configuration.xml file * * @param configuration * @param moduleName * @param projectOperations */ public static void updateRepositories(final Element configuration, String path, ProjectOperations projectOperations) { final List<Repository> repositories = new ArrayList<Repository>(); final List<Element> geoRepositories = XmlUtils.findElements(path, configuration); for (final Element repositoryElement : geoRepositories) { repositories.add(new Repository(repositoryElement)); } projectOperations.addRepositories( projectOperations.getFocusedModuleName(), repositories); } /** * * This method update dependencies with the added to configuration.xml file * * @param configuration * @param moduleName * @param projectOperations */ public static void updateDependencies(final Element configuration, String path, ProjectOperations projectOperations) { final List<Dependency> dependencies = new ArrayList<Dependency>(); final List<Element> geoDependencies = XmlUtils.findElements(path, configuration); for (final Element dependencyElement : geoDependencies) { dependencies.add(new Dependency(dependencyElement)); } projectOperations.addDependencies( projectOperations.getFocusedModuleName(), dependencies); } /** * This method transform current dialect to a valid dialect to use in * Hibernate Spatial * * @param currentDialect * @return */ public static String convertToGeoDialect(final Element configuration, String currentDialect) { Map<String, String> dialects = getDialects(configuration); String geoDialect = dialects.get(currentDialect); if (geoDialect != null) { return geoDialect; } return null; } /** * This method checks if the current dialect is a valid Geo dialect to use * in Hibernate Spatial * * @param currentDialect * @return */ public static boolean isGeoDialect(final Element configuration, String currentDialect) { Map<String, String> geoDialects = getGeoDialects(configuration); String geoDialect = geoDialects.get(currentDialect); if (geoDialect != null) { return true; } return false; } /** * This method returns a Map with Dialects and the GEO dialects associated * * @return */ public static Map<String, String> getDialects(final Element configuration) { Map<String, String> dialects = new HashMap<String, String>(); final List<Element> geoDialects = XmlUtils.findElements( "/configuration/dialects/dialect", configuration); for (final Element dialectElement : geoDialects) { String id = dialectElement.getAttribute("id"); String value = dialectElement.getAttribute("value"); dialects.put(id, value); } return dialects; } /** * This method returns a Map with GeoDialects and the dialects associated * * @return */ public static Map<String, String> getGeoDialects(final Element configuration) { Map<String, String> dialects = new HashMap<String, String>(); final List<Element> geoDialects = XmlUtils.findElements( "/configuration/dialects/dialect", configuration); for (final Element dialectElement : geoDialects) { String id = dialectElement.getAttribute("id"); String value = dialectElement.getAttribute("value"); dialects.put(value, id); } return dialects; } /** * * Checks if Hibernate Spatial is installed * * @param fileManager * @param pathResolver * @param currentClass * @return */ public static boolean isHibernateSpatialPersistenceInstalled( FileManager fileManager, PathResolver pathResolver, Class currentClass) { // persistence.xml file final String persistenceFile = pathResolver.getFocusedIdentifier( Path.SRC_MAIN_RESOURCES, "META-INF/persistence.xml"); // if persistence.xml doesn't exists show a WARNING if (fileManager.exists(persistenceFile)) { // Getting document final Document persistenceXmlDocument = XmlUtils .readXml(fileManager.getInputStream(persistenceFile)); final Element persistenceElement = persistenceXmlDocument .getDocumentElement(); // Getting all persistence-unit NodeList nodes = persistenceElement.getChildNodes(); // Saving in variables, which nodes could be changed int totalModified = 0; for (int i = 0; i < nodes.getLength(); i++) { Node persistenceUnit = nodes.item(i); // Get all items of current persistence-unit NodeList childNodes = persistenceUnit.getChildNodes(); for (int x = 0; x < childNodes.getLength(); x++) { Node childNode = childNodes.item(x); String nodeName = childNode.getNodeName(); if ("properties".equals(nodeName)) { // Getting all properties NodeList properties = childNode.getChildNodes(); for (int y = 0; y < properties.getLength(); y++) { Node property = properties.item(y); // Getting attribute properties NamedNodeMap attributes = property.getAttributes(); if (attributes != null) { Node propertyName = attributes .getNamedItem("name"); String propertyNameValue = propertyName .getNodeValue(); if ("hibernate.dialect" .equals(propertyNameValue)) { Node propertyValue = attributes .getNamedItem("value"); String value = propertyValue.getNodeValue(); final Element configuration = XmlUtils .getConfiguration(currentClass); if (HibernateSpatialGeoUtils.isGeoDialect( configuration, value)) { totalModified++; } else if ("${".equals(value.substring(0, 2))) { totalModified++; } } } } } } } if (totalModified != 0) { // return true; return isHibernateSpatialDependenceInstalled(fileManager, pathResolver); } else { return false; } } else { throw new RuntimeException( "ERROR: Error getting persistence.xml file"); } } /** * Checks if Hibernate Spatial dependencies are installed * * @param fileManager * @param pathResolver * @param currentClass * @return */ public static boolean isHibernateSpatialDependenceInstalled( FileManager fileManager, PathResolver pathResolver) { // Pom root element String pom = pathResolver.getIdentifier( LogicalPath.getInstance(Path.ROOT, ""), "pom.xml"); if (fileManager.exists(pom)) { // Getting document Document doc = XmlUtils.readXml(fileManager.getInputStream(pom)); NodeList allArtifactId = doc.getElementsByTagName("artifactId"); for (int i = 0; i < allArtifactId.getLength(); i++) { Element artifactId = (Element) allArtifactId.item(i); if ("hibernate-spatial".equals(artifactId.getTextContent())) { return true; } } } return false; } /** * This method generates package-info.java on current entity package. If * <b>package-info.java</b> is generated on current entity package, don't * replace or change. If <b>package-info.java</b> is not generated on * current entity package, generate it with necessary GEO configuration. * * @param entityPackage * @param pathResolver * @param fileManager * @return */ public static boolean generatePackageInfoIfNotExists( JavaPackage entityPackage, PathResolver pathResolver, FileManager fileManager) { if (entityPackage != null) { // Getting package String stringPackage = entityPackage.getFullyQualifiedPackageName(); if (StringUtils.isNotBlank(stringPackage)) { // Generating final path String packageInfoPath = stringPackage.replaceAll("\\.", "/") + "/package-info.java"; final String finalPath = pathResolver.getFocusedIdentifier( Path.SRC_MAIN_JAVA, packageInfoPath); // If file not exists, create new one if (!fileManager.exists(finalPath)) { MutableFile file = fileManager.createFile(finalPath); OutputStream outputStream = file.getOutputStream(); // Modifying created file if (outputStream != null) { PrintWriter writer = new PrintWriter(outputStream); writer.println("@org.hibernate.annotations.TypeDefs({ "); writer.println(" @org.hibernate.annotations.TypeDef(name=\"geometry\", "); writer.println(" typeClass = org.hibernate.spatial.GeometryType.class)"); writer.println("})"); writer.println(String.format("package %s;", stringPackage)); writer.flush(); writer.close(); } } else { // Return true if exists return true; } } } return true; } }