/* * 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.web.exception.handler.roo.addon.addon; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.SortedSet; import java.util.logging.Logger; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.gvnix.support.MessageBundleUtils; import org.gvnix.support.OperationUtils; import org.gvnix.support.WebProjectUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; import org.springframework.roo.addon.propfiles.PropFileOperations; import org.springframework.roo.addon.web.mvc.jsp.i18n.I18nSupport; import org.springframework.roo.addon.web.mvc.jsp.tiles.TilesOperations; import org.springframework.roo.addon.web.mvc.jsp.tiles.TilesOperationsImpl; import org.springframework.roo.file.monitor.event.FileDetails; import org.springframework.roo.metadata.MetadataService; import org.springframework.roo.process.manager.FileManager; import org.springframework.roo.process.manager.MutableFile; 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.support.logging.HandlerUtils; import org.springframework.roo.support.util.FileUtils; import org.springframework.roo.support.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Implementation of Exception commands that are available via the Roo shell. * * @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> */ @Component @Service public class WebExceptionHandlerOperationsImpl implements WebExceptionHandlerOperations { private static final String ITD_TEMPLATE = "exception.jspx"; private static final String ENGLISH_LANGUAGE_FILENAME = "/WEB-INF/i18n/messages.properties"; private static final String LANGUAGE_FILENAMES = "WEB-INF/i18n/messages**.properties"; private static final String FOLDER_SEPARATOR = "/"; private static final Logger LOGGER = HandlerUtils .getLogger(WebModalDialogOperationsImpl.class); private static final String WEB_MVC_CONFIG = "WEB-INF/spring/webmvc-config.xml"; private static final String WEB_MVC_CONFIG_NOT_FOUND = "webmvc-config.xml not found"; private static final String RESOLVER_BEAN_MESSAGE = "/beans/bean[@id='messageMappingExceptionResolverBean']"; private static final String JSPX_EXTENSION = ".jspx"; private static final String ERROR = "error."; private static final String TITLE = ".title"; private static final String PROBLEM_DESCRIPTION = ".problemdescription"; private static final String IMP_IDENTIFIER_GENERATION_EXCEPTION = "org.hibernate.id.IdentifierGenerationException"; private static final String IDENTIFIER_GENERATION_EXCEPTION = "IdentifierGenerationException"; @Reference private ProjectOperations projectOperations; @Reference private TilesOperations tilesOperations; @Reference private FileManager fileManager; @Reference private MetadataService metadataService; @Reference private PathResolver pathResolver; @Reference private PropFileOperations propFileOperations; @Reference private I18nSupport i18nSupport; private WebProjectUtils webProjectUtils; private MessageBundleUtils messageBundleUtils; private OperationUtils operationUtils; // ------------ OSGi component attributes ---------------- private BundleContext context; protected void activate(ComponentContext cContext) { context = cContext.getBundleContext(); } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #getHandledExceptionList() */ public String getHandledExceptionList() { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); Validate.isTrue(fileManager.exists(webXmlPath), WEB_MVC_CONFIG_NOT_FOUND); MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); List<Element> simpleMappingException = null; simpleMappingException = XmlUtils.findElements(RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props/prop", root); Validate.notNull(simpleMappingException, "There aren't Exceptions handled by the application."); StringBuilder exceptionList = new StringBuilder("Handled Exceptions:\n"); for (Element element : simpleMappingException) { exceptionList.append(element.getAttribute("key") + "\n"); } return exceptionList.toString(); } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #addNewHandledException(java.lang.String, java.lang.String, * java.lang.String, java.lang.String) */ public void addNewHandledException(String exceptionName, String exceptionTitle, String exceptionDescription, String exceptionLanguage) { Validate.notNull(exceptionName, "You have to provide a Exception Name."); Validate.notNull(exceptionTitle, "You have to provide a Exception Title."); Validate.notNull(exceptionDescription, "You have to provide a Exception Description."); // Update webmvcconfig.xml and retrieve the exception view name. // Returns the exceptionViewName. String exceptionViewName = updateWebMvcConfig(exceptionName); // Create .jspx Exception file. createNewExceptionView(exceptionName, exceptionTitle, exceptionDescription, exceptionViewName); // Update views.xml updateViewsLayout(exceptionViewName); // Add the message property to identify the new Exception. String exceptionFileName = getLanguagePropertiesFile(exceptionLanguage); createMultiLanguageMessages(exceptionName, exceptionTitle, exceptionDescription, exceptionFileName); } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #removeExceptionHandled(java.lang.String) */ public void removeExceptionHandled(String exceptionName) { Validate.notNull(exceptionName, "You have to provide a Exception Name."); // Remove Exception mapping String exceptionViewName = removeWebMvcConfig(exceptionName); // Remove view definition. removeViewsLayout(exceptionViewName); // Remove Exception jspx view. removeExceptionView(exceptionViewName); // Remove multiLanguage messages. removeMultiLanguageMessages(exceptionName); } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #languageExceptionHandled(java.lang.String, java.lang.String, * java.lang.String, java.lang.String) */ public void languageExceptionHandled(String exceptionName, String exceptionTitle, String exceptionDescription, String exceptionLanguage) { // Checks if the Exception is handled by the // SimpleMappingExceptionResolver existException(exceptionName); // Retrieves the existing messages FileName in the selected Language. String exceptionFileName = getLanguagePropertiesFile(exceptionLanguage); // Updates the selected language properties fileName for the Exception. updateMultiLanguageMessages(exceptionName, exceptionTitle, exceptionDescription, exceptionFileName); } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #getLanguagePropertiesFile(java.lang.String) */ public String getLanguagePropertiesFile(String exceptionLanguage) { getMessageBundleUtils().installI18nMessages( i18nSupport.getLanguage(new Locale(exceptionLanguage)), projectOperations, fileManager); String languagePath; if (exceptionLanguage.compareTo("en") == 0) { languagePath = ENGLISH_LANGUAGE_FILENAME; } else { languagePath = "WEB-INF/i18n/messages_" + exceptionLanguage + ".properties"; } String messagesPath = pathResolver .getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), languagePath); Validate.isTrue( fileManager.exists(messagesPath), languagePath + "\t Language properties file not found.\nTry another Language: [es, de, it, nl, sv, en]."); return languagePath; } /** * Checks if the Exception is mapped in the SimpleMappingExceptionResolver * Controller * * @param exceptionName Exception Name to Handle. */ private void existException(String exceptionName) { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); Validate.isTrue(fileManager.exists(webXmlPath), WEB_MVC_CONFIG_NOT_FOUND); MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); Element exceptionResolver = XmlUtils .findFirstElement( RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props/prop[@key='" + exceptionName + "']", root); Validate.isTrue(exceptionResolver != null, "There isn't a Exception Handled with the name:\t" + exceptionName); } /** * Update the webmvc-config.xml with the new Exception. * * @param exceptionName Exception Name to Handle. * @return {@link String} The exceptionViewName to create the .jspx view. */ protected String updateWebMvcConfig(String exceptionName) { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); Validate.isTrue(fileManager.exists(webXmlPath), WEB_MVC_CONFIG_NOT_FOUND); MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); Element simpleMappingException = XmlUtils.findFirstElement( RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props", root); Element exceptionResolver = XmlUtils .findFirstElement( RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props/prop[@key='" + exceptionName + "']", root); boolean updateMappings = false; boolean updateController = false; // View name for this Exception. String exceptionViewName; if (exceptionResolver != null) { exceptionViewName = exceptionResolver.getTextContent(); } else { updateMappings = true; exceptionViewName = getExceptionViewName(exceptionName); } Element newExceptionMapping; // Exception Mapping newExceptionMapping = webXml.createElement("prop"); newExceptionMapping.setAttribute("key", exceptionName); Validate.isTrue(exceptionViewName != null, "Can't create the view for the:\t" + exceptionName + " Exception."); newExceptionMapping.setTextContent(exceptionViewName); if (updateMappings) { simpleMappingException.appendChild(newExceptionMapping); } // Exception Controller Element newExceptionView = XmlUtils.findFirstElement( "/beans/view-controller[@path='/" + exceptionViewName + "']", root); if (newExceptionView == null) { updateController = true; } newExceptionView = webXml.createElementNS( "http://www.springframework.org/schema/mvc", "view-controller"); newExceptionView.setPrefix("mvc"); newExceptionView.setAttribute("path", "/" + exceptionViewName); if (updateController) { root.appendChild(newExceptionView); } if (updateMappings || updateController) { XmlUtils.writeXml(webXmlMutableFile.getOutputStream(), webXml); } return exceptionViewName; } /** * Returns the exception view name checking if exists in the file * webmvc-config.xml file. * * @param exceptionName to create the view. * @param root {@link Element} with the values off webmvc-config.xml * @return */ private String getExceptionViewName(String exceptionName) { // View name for this Exception. int index = exceptionName.lastIndexOf('.'); String exceptionViewName = exceptionName; if (index >= 0) { exceptionViewName = exceptionName.substring(index + 1); } exceptionViewName = StringUtils.uncapitalize(exceptionViewName); boolean exceptionNameExists = true; int exceptionCounter = 2; String tmpExceptionViewName = exceptionViewName; while (exceptionNameExists) { exceptionNameExists = fileManager.exists(pathResolver .getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), "WEB-INF/views/" + tmpExceptionViewName + JSPX_EXTENSION)); if (exceptionNameExists) { tmpExceptionViewName = exceptionViewName.concat(Integer .toString(exceptionCounter++)); } } return tmpExceptionViewName; } /** * Removes the definition of the selected Exception in the webmvc-config.xml * file. * * @param exceptionName Exception Name to remove. */ private String removeWebMvcConfig(String exceptionName) { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); Validate.isTrue(fileManager.exists(webXmlPath), WEB_MVC_CONFIG_NOT_FOUND); MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); Element exceptionResolver = XmlUtils .findFirstElement( RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props/prop[@key='" + exceptionName + "']", root); Validate.isTrue(exceptionResolver != null, "There isn't a Handled Exception with the name:\t" + exceptionName); // Remove Mapping exceptionResolver.getParentNode().removeChild(exceptionResolver); String exceptionViewName = exceptionResolver.getTextContent(); Validate.isTrue(exceptionViewName != null, "Can't remove the view for the:\t" + exceptionName + " Exception."); // Remove NameSpace bean. Element lastExceptionControlled = XmlUtils.findFirstElement( "/beans/view-controller[@path='/" + exceptionViewName + "']", root); lastExceptionControlled.getParentNode().removeChild( lastExceptionControlled); XmlUtils.writeXml(webXmlMutableFile.getOutputStream(), webXml); return exceptionViewName; } /** * Update layout.xml to map the new Exception associated View. * * @param exceptionViewName to create the view and the definition in the xml */ private void updateViewsLayout(String exceptionViewName) { // Exception view - create a view to show the exception message. String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), "WEB-INF/views/views.xml"); Validate.isTrue(fileManager.exists(webXmlPath), "views.xml not found"); String jspxPath = "/WEB-INF/views/" + exceptionViewName + JSPX_EXTENSION; tilesOperations.addViewDefinition("", LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), exceptionViewName, TilesOperationsImpl.PUBLIC_TEMPLATE, jspxPath); } /** * Removes the definition of the Exception view in layout.xml. * * @param exceptionViewName Exception Name to remove. */ private void removeViewsLayout(String exceptionViewName) { // Exception view - create a view to show the exception message. String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), "WEB-INF/views/views.xml"); Validate.isTrue(fileManager.exists(webXmlPath), "views.xml not found"); tilesOperations.removeViewDefinition(exceptionViewName, "", LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, "")); } /** * Creates a view for the new Handled Exception. * * @param exceptionName Name of the Exception to handle. * @param exceptionTitle Title of the exception view. * @param exceptionDescription Description to show in the view. * @param exceptionViewName Name of the .jspx view. */ private void createNewExceptionView(String exceptionName, String exceptionTitle, String exceptionDescription, String exceptionViewName) { String exceptionNameUncapitalize = StringUtils .uncapitalize(exceptionName); Map<String, String> params = new HashMap<String, String>(10); // Parameters params.put("error.uncaughtexception.title", ERROR + exceptionNameUncapitalize + TITLE); params.put("error.uncaughtexception.problemdescription", ERROR + exceptionNameUncapitalize + PROBLEM_DESCRIPTION); String exceptionFilename = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), "WEB-INF/views/" + exceptionViewName + JSPX_EXTENSION); String template; try { InputStream templateInputStream = FileUtils.getInputStream( getClass(), ITD_TEMPLATE); InputStreamReader readerFile = new InputStreamReader( templateInputStream); template = IOUtils.toString(readerFile); } catch (IOException ioe) { throw new IllegalStateException("Unable load ITD jspx template", ioe); } template = replaceParams(template, params); // Output the ITD if there is actual content involved // (if there is no content, we continue on to the deletion phase // at the bottom of this conditional block) Validate.isTrue(template.length() > 0, "The template doesn't exists."); MutableFile mutableFile = null; if (fileManager.exists(exceptionFilename)) { File newFile = new File(exceptionFilename); String existing = null; try { existing = IOUtils.toString(new FileReader(newFile)); } catch (IOException ignoreAndJustOverwriteIt) { LOGGER.finest("Problems writting ".concat(newFile .getAbsolutePath())); } if (!template.equals(existing)) { mutableFile = fileManager.updateFile(exceptionFilename); } } else { mutableFile = fileManager.createFile(exceptionFilename); Validate.notNull(mutableFile, "Could not create ITD file '" + exceptionFilename + "'"); } try { if (mutableFile != null) { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = IOUtils.toInputStream(template); outputStream = mutableFile.getOutputStream(); IOUtils.copy(inputStream, outputStream); } finally { IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(outputStream); } } } catch (IOException ioe) { throw new IllegalStateException("Could not output '" + mutableFile.getCanonicalPath() + "'", ioe); } } /** * Removes Exception view .jspx. * * @param exceptionViewName Exception Name to remove. */ private void removeExceptionView(String exceptionViewName) { String exceptionFilename = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), "WEB-INF/views/" + exceptionViewName + JSPX_EXTENSION); fileManager.delete(exceptionFilename); } /** * Method to replace the parameters set in the Map into the template. * * @param template Template to create a new jspx. * @param params {@link Map} with the specified parameters. * @return {@link String} with the updated parameters values. */ private String replaceParams(String template, Map<String, String> params) { for (Entry<String, String> entry : params.entrySet()) { template = StringUtils.replace(template, "${" + entry.getKey() + "}", entry.getValue()); } return template; } /** * Updates the selected language file with the title and the description of * the new Exception. * * @param exceptionName Name of the Exception. * @param exceptionTitle Title of the Exception. * @param exceptionDescription Description of the Exception. */ private void createMultiLanguageMessages(String exceptionName, String exceptionTitle, String exceptionDescription, String propertyFileName) { String exceptionNameUncapitalize = StringUtils .uncapitalize(exceptionName); SortedSet<FileDetails> propertiesFiles = getPropertiesFiles(); Map<String, String> params = new HashMap<String, String>(10); // Parameters params.put(ERROR + exceptionNameUncapitalize + TITLE, exceptionTitle); params.put(ERROR + exceptionNameUncapitalize + PROBLEM_DESCRIPTION, exceptionDescription); String propertyFilePath = "/WEB-INF/i18n/"; String canonicalPath; String fileName; String tmpProperty; for (Entry<String, String> entry : params.entrySet()) { for (FileDetails fileDetails : propertiesFiles) { canonicalPath = fileDetails.getCanonicalPath(); fileName = propertyFilePath.concat(getFilename(canonicalPath)); if (propertyFileName.compareTo(fileName.substring(1)) == 0) { tmpProperty = propFileOperations.getProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), fileName, entry.getKey()); if (tmpProperty == null) { propFileOperations.changeProperty(LogicalPath .getInstance(Path.SRC_MAIN_WEBAPP, ""), propertyFileName, entry.getKey(), entry .getValue()); } else if (tmpProperty.compareTo(entry.getValue()) != 0) { propFileOperations.changeProperty(LogicalPath .getInstance(Path.SRC_MAIN_WEBAPP, ""), propertyFileName, entry.getKey(), entry .getValue()); } } else { // Updates the file if the property doesn't exists. if (propFileOperations.getProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), fileName, entry.getKey()) == null) { propFileOperations.changeProperty(LogicalPath .getInstance(Path.SRC_MAIN_WEBAPP, ""), fileName, entry.getKey(), entry.getKey()); } } } } } /** * Updates the selected language file with the title and the description of * the new Exception. * * @param exceptionName Name of the Exception. * @param exceptionTitle Title of the Exception. * @param exceptionDescription Description of the Exception. */ private void updateMultiLanguageMessages(String exceptionName, String exceptionTitle, String exceptionDescription, String propertyFileName) { String exceptionNameUncapitalize = StringUtils .uncapitalize(exceptionName); Map<String, String> params = new HashMap<String, String>(10); // Parameters params.put(ERROR + exceptionNameUncapitalize + TITLE, exceptionTitle); params.put(ERROR + exceptionNameUncapitalize + PROBLEM_DESCRIPTION, exceptionDescription); for (Entry<String, String> entry : params.entrySet()) { String tmpProperty = propFileOperations.getProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), propertyFileName, entry.getKey()); if (tmpProperty == null) { propFileOperations.changeProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), propertyFileName, entry.getKey(), entry.getValue()); } else if (tmpProperty.compareTo(entry.getValue()) != 0) { propFileOperations.changeProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), propertyFileName, entry.getKey(), entry.getValue()); } } } /** * Removes the Language messages properties of the Exception. * * @param exceptionName Exception Name to remove. */ private void removeMultiLanguageMessages(String exceptionName) { String exceptionNameUncapitalize = StringUtils .uncapitalize(exceptionName); SortedSet<FileDetails> propertiesFiles = getPropertiesFiles(); Map<String, String> params = new HashMap<String, String>(10); // Parameters params.put(ERROR + exceptionNameUncapitalize + TITLE, ""); params.put(ERROR + exceptionNameUncapitalize + PROBLEM_DESCRIPTION, ""); String propertyFilePath = "/WEB-INF/i18n/"; String fileName; String canonicalPath; for (Entry<String, String> entry : params.entrySet()) { for (FileDetails fileDetails : propertiesFiles) { canonicalPath = fileDetails.getCanonicalPath(); fileName = propertyFilePath.concat(getFilename(canonicalPath)); propFileOperations.removeProperty( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), fileName, entry.getKey()); } } } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #setUpGvNIXExceptions() */ public void setUpGvNIXExceptions() { // java.sql.SQLException addNewHandledException("java.sql.SQLException", "SQLException", "Se ha producido un error en el acceso a la Base de datos.", "es"); languageExceptionHandled("java.sql.SQLException", "SQLException", "S'ha produït un error en l'accés a la Base de dades.", "ca"); languageExceptionHandled("java.sql.SQLException", "SQLException", "There was an error accessing the database.", "en"); // java.io.IOException addNewHandledException("java.io.IOException", "IOException", "Existen problemas para enviar o recibir datos.", "es"); languageExceptionHandled("java.io.IOException", "IOException", "Hi ha problemes per enviar o rebre dades.", "ca"); languageExceptionHandled("java.io.IOException", "IOException", "There are problems sending or receiving data.", "en"); // org.springframework.transaction.TransactionException addNewHandledException( "org.springframework.transaction.TransactionException", "TransactionException", "Se ha producido un error en la transacción. No se han guardado los datos correctamente.", "es"); languageExceptionHandled( "org.springframework.transaction.TransactionException", "TransactionException", "S'ha produït un error en la transacció. No s'han guardat les dades correctament.", "ca"); languageExceptionHandled( "org.springframework.transaction.TransactionException", "TransactionException", "There was an error in the transaction. No data have been stored properly.", "en"); // java.lang.UnsupportedOperationException addNewHandledException("java.lang.UnsupportedOperationException", "UnsupportedOperationException", "Se ha producido un error no controlado.", "es"); languageExceptionHandled("java.lang.UnsupportedOperationException", "UnsupportedOperationException", "S'ha produït un error no controlat.", "ca"); languageExceptionHandled("java.lang.UnsupportedOperationException", "UnsupportedOperationException", "There was an unhandled error.", "en"); // javax.persistence.OptimisticLockException addNewHandledException( "javax.persistence.OptimisticLockException", "OptimisticLockException", "No se puede actualizar el registro debido a que ha sido actualizado previamente.", "es"); languageExceptionHandled( "javax.persistence.OptimisticLockException", "OptimisticLockException", "No es pot actualitzar el registre a causa de que s'ha actualitzat prèviament.", "ca"); languageExceptionHandled( "javax.persistence.OptimisticLockException", "OptimisticLockException", "Can not update the record because it has been previously updated.", "en"); // org.hibernate.NonUniqueObjectException addNewHandledException( "org.hibernate.NonUniqueObjectException", "NonUniqueObjectException", "No se puede crear el registro porque existe un objeto distinto con el mismo identificador.", "es"); languageExceptionHandled( "org.hibernate.NonUniqueObjectException", "NonUniqueObjectException", "No es pot crear el registre perque existeix un altre objecte amb el mateix identificador.", "ca"); languageExceptionHandled( "org.hibernate.NonUniqueObjectException", "NonUniqueObjectException", "Can not create the record because a different object with the same identifier value already exists.", "en"); // org.hibernate.exception.ConstraintViolationException addNewHandledException( "org.hibernate.exception.ConstraintViolationException", "ConstraintViolationException", "No se puede crear/actualizar el registro porque no se cumple una restricción de integridad.", "es"); languageExceptionHandled( "org.hibernate.exception.ConstraintViolationException", "ConstraintViolationException", "No es pot crear/actualiztar el registre perque no es compleix una restricció d'integritat.", "ca"); languageExceptionHandled( "org.hibernate.exception.ConstraintViolationException", "ConstraintViolationException", "Can not create/update the record because a violation of a defined integrity constraint.", "en"); // org.hibernate.id.IdentifierGenerationException addNewHandledException( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "No se puede crear porque alguno de los campos que que conforman el identificador del registro no ha sido informado.", "es"); languageExceptionHandled( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "No es pot crear perque algun dels camps que conformen l'identificador del registre no ha estat informat.", "ca"); languageExceptionHandled( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "Can not create the record because any of the field comprising the identifier of the record has not been informed.", "en"); // org.hibernate.id.IdentifierGenerationException addNewHandledException( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "No se puede crear porque alguno de los campos que que conforman el identificador del registro no ha sido informado.", "es"); languageExceptionHandled( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "No es pot crear perque algun dels camps que conformen l'identificador del registre no ha estat informat.", "ca"); languageExceptionHandled( IMP_IDENTIFIER_GENERATION_EXCEPTION, IDENTIFIER_GENERATION_EXCEPTION, "Can not create the record because any of the field comprising the identifier of the record has not been informed.", "en"); } /** * Retrieves the messages properties files of the application * * @return {@link SortedSet} with the messages properties files */ private SortedSet<FileDetails> getPropertiesFiles() { SortedSet<FileDetails> propertiesFiles = fileManager .findMatchingAntPath(pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), LANGUAGE_FILENAMES)); return propertiesFiles; } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #isExceptionMappingAvailable() */ public boolean isExceptionMappingAvailable() { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); if (!fileManager.exists(webXmlPath)) { return false; } MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); Element exceptionResolver = XmlUtils .findFirstElement( "/beans/bean[@class='org.springframework.web.servlet.handler.SimpleMappingExceptionResolver']" + "/property[@name='exceptionMappings']/props/prop", root); boolean isExceptionAvailable = (exceptionResolver != null) ? true : false; return isExceptionAvailable; } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #isExceptionMappingAvailable() */ public boolean isMessageMappingAvailable() { String webXmlPath = pathResolver.getIdentifier( LogicalPath.getInstance(Path.SRC_MAIN_WEBAPP, ""), WEB_MVC_CONFIG); if (!fileManager.exists(webXmlPath)) { return false; } MutableFile webXmlMutableFile = null; Document webXml; try { webXmlMutableFile = fileManager.updateFile(webXmlPath); webXml = XmlUtils.getDocumentBuilder().parse( webXmlMutableFile.getInputStream()); } catch (Exception e) { throw new IllegalStateException(e); } Element root = webXml.getDocumentElement(); Element exceptionResolver = XmlUtils.findFirstElement( RESOLVER_BEAN_MESSAGE + "/property[@name='exceptionMappings']/props/prop", root); boolean isExceptionAvailable = (exceptionResolver != null) ? true : false; return isExceptionAvailable; } /* * (non-Javadoc) * * @see * org.gvnix.web.exception.handler.roo.addon.WebExceptionHandlerOperations * #isProjectAvailable() */ public boolean isProjectAvailable() { return getOperationUtils().isProjectAvailable(metadataService, projectOperations) && getWebProjectUtils().isSpringMvcProject(metadataService, fileManager, projectOperations); } /** * Extract the filename from the given path, e.g. "mypath/myfile.txt" -> * "myfile.txt". * * @param path the file path (may be <code>null</code>) * @return the extracted filename, or <code>null</code> if none */ public static String getFilename(String path) { if (path == null) { return null; } int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path); } public WebProjectUtils getWebProjectUtils() { if (webProjectUtils == null) { // Get all Services implement WebProjectUtils interface try { ServiceReference<?>[] references = this.context .getAllServiceReferences( WebProjectUtils.class.getName(), null); for (ServiceReference<?> ref : references) { webProjectUtils = (WebProjectUtils) this.context .getService(ref); return webProjectUtils; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load WebProjectUtils on WebExceptionHandlerOperationsImpl."); return null; } } else { return webProjectUtils; } } public MessageBundleUtils getMessageBundleUtils() { if (messageBundleUtils == null) { // Get all Services implement MessageBundleUtils interface try { ServiceReference<?>[] references = this.context .getAllServiceReferences( MessageBundleUtils.class.getName(), null); for (ServiceReference<?> ref : references) { messageBundleUtils = (MessageBundleUtils) this.context .getService(ref); return messageBundleUtils; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load MessageBundleUtils on WebExceptionHandlerOperationsImpl."); return null; } } else { return messageBundleUtils; } } public OperationUtils getOperationUtils() { if (operationUtils == null) { // Get all Services implement OperationUtils interface try { ServiceReference<?>[] references = this.context .getAllServiceReferences( OperationUtils.class.getName(), null); for (ServiceReference<?> ref : references) { operationUtils = (OperationUtils) this.context .getService(ref); return operationUtils; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load OperationUtils on WebExceptionHandlerOperationsImpl."); return null; } } else { return operationUtils; } } }