/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.runtime.ui.wizards.webservices.util; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.tools.Diagnostic; import javax.tools.Diagnostic.Kind; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.core.designer.util.FileUtils; import org.teiid.core.designer.util.StringConstants; import org.teiid.core.designer.util.TempDirectory; import org.teiid.designer.DesignerSPIPlugin; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.runtime.ui.wizards.webservices.WarDeploymentInfoPanel; import org.teiid.designer.runtime.version.spi.ITeiidServerVersion; import org.teiid.designer.runtime.version.spi.TeiidServerVersion; import org.teiid.designer.webservice.WebServicePlugin; import org.teiid.designer.webservice.lib.WebServiceLibConstants; import org.teiid.designer.webservice.lib.WebServiceLibPlugin; import org.teiid.designer.webservice.util.AntTasks; /** * This is the default implementation of a WebArchiveBuilder. * * @since 8.0 */ public class RestWebArchiveBuilderImpl implements WebArchiveBuilder, WebServiceLibConstants, StringConstants { private IPath webServicePluginPath = null; private List<String> models = new ArrayList<String>(); private Map<String, List<RestProcedure>> modelMapOfProcedures = new HashMap<String, List<RestProcedure>>(); File webXmlFile = null; public static String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ // ============================================================= // Constants // ============================================================= private static final String I18N_PREFIX = "WebArchiveBuilder."; //$NON-NLS-1$ private static final String TASK_CREATE_DIRECTORIES = getString("taskCreateDirectory"); //$NON-NLS-1$ private static final String TASK_COPYING_FILES = getString("taskCopyingFiles"); //$NON-NLS-1$ private static final String TASK_CREATING_WAR_ARCHIVE = getString("taskCreatingWarArchive"); //$NON-NLS-1$ private static final String TASK_COPYING_WAR_FILE = getString("taskCopyingWarFile"); //$NON-NLS-1$ private static final String TASK_CLEANUP = getString("taskCleanup"); //$NON-NLS-1$ private static final String JNDI_PREFIX = "java:"; //$NON-NLS-1$ /** * This constructor is package protected, so that only the factory can call it. * * @since 7.4 */ protected RestWebArchiveBuilderImpl() { } /** * @return modelMapOfProcedures */ public Map<String, List<RestProcedure>> getModelMapOfProcedures() { return modelMapOfProcedures; } /** * @param modelMapOfProcedures Sets modelMapOfProcedures to the specified value. */ public void setModelMapOfProcedures( Map<String, List<RestProcedure>> modelMapOfProcedures ) { this.modelMapOfProcedures = modelMapOfProcedures; } @Override public IStatus validateContextName( String contextName ) { try { final String URL_BASE = "http://www.teiid.org/"; //$NON-NLS-1$ final URLValidator urlValidator = new URLValidator(); // Check for invalid characters String[] invalidChars = new String[] {"/" //$NON-NLS-1$ , "\\" //$NON-NLS-1$ , CoreStringUtil.Constants.SPACE}; final String invalidChar = validateInvalidCharactersInContextName(contextName, invalidChars); // Perform validation if (invalidChar != null) { String msg = null; if (CoreStringUtil.Constants.SPACE.equals(invalidChar)) { msg = getString("ContextNameValidationFailed_InvalidSpace"); //$NON-NLS-1$ } else { final Object[] params = new Object[] {invalidChar}; msg = getString("ContextNameValidationFailed_InvalidCharacter", params); //$NON-NLS-1$ } return new Status(IStatus.ERROR, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_CONTEXT_NAME_VALIDATION_FAILED, msg, null); } else if (CoreStringUtil.Constants.EMPTY_STRING.equals(contextName)) { final String msg = getString("ContextNameValidationFailed_Empty"); //$NON-NLS-1$ return new Status(IStatus.ERROR, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_CONTEXT_NAME_VALIDATION_FAILED, msg, null); } else if (!urlValidator.isValidValue(URL_BASE + contextName)) { final String msg = getString("ContextNameValidationFailed"); //$NON-NLS-1$ return new Status(IStatus.ERROR, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_CONTEXT_NAME_VALIDATION_FAILED, msg, null); } else { final String msg = getString("ContextNameValidationSucceeded"); //$NON-NLS-1$ return new Status(IStatus.OK, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_CONTEXT_NAME_VALIDATION_SUCCEEDED, msg, null); } } catch (Exception e) { final String msg = getString("ContextNameValidationFailed"); //$NON-NLS-1$ return new Status(IStatus.ERROR, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_CONTEXT_NAME_VALIDATION_FAILED, msg, e); } } /** * @see org.teiid.designer.runtime.ui.wizards.webservices.util.WebArchiveBuilder#createWebArchive(Properties, IProgressMonitor) * @since 7.4 */ @Override public IStatus createWebArchive( Properties properties, IProgressMonitor monitor ) { try { // Get and validate the context name. final String contextName = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); IStatus status = validateContextName(contextName); if (IStatus.ERROR == status.getSeverity()) { throw new Exception(status.getException()); } modelMapOfProcedures = (Map<String, List<RestProcedure>>)properties.get(WebArchiveBuilderConstants.PROPERTY_VDB_REST_PROCEDURES); setModels(modelMapOfProcedures); // Get the build directory and create it if it doesn't already // exist. final String webServicePluginPath = WebServiceLibPlugin.getDefault().getInstallPath().toOSString(); final String buildDirectoryName = webServicePluginPath + File.separator + WebArchiveBuilderConstants.REST_BUILD_DIR; File buildDirectory = new File(buildDirectoryName); buildDirectory.mkdir(); monitor.subTask(TASK_CREATE_DIRECTORIES); // Get the work directory, create it (in case it is not there) and // try to empty it. final String workDirectoryName = buildDirectoryName + File.separator + WebArchiveBuilderConstants.WORK_DIR; File workDirectory = new File(workDirectoryName); workDirectory.mkdir(); FileUtils.removeChildrenRecursively(workDirectory); // Create the temporary directory. final TempDirectory tempDir = TempDirectory.getTempDirectory(workDirectoryName); final String tempDirectoryName = tempDir.getPath(); // Create context directory. final String contextDirectoryName = tempDirectoryName + File.separator + contextName; final File contextDirectory = new File(contextDirectoryName); contextDirectory.mkdir(); // Create the WEB-INF directory. final String webInfDirectoryName = contextDirectoryName + File.separator + WEB_INF; final File webInfDirectory = new File(webInfDirectoryName); webInfDirectory.mkdir(); // Create the classes directory. final String webInfClassesDirectoryName = webInfDirectoryName + File.separator + CLASSES; // Create the classes directory. final String webInfLibDirectoryName = webInfDirectoryName + File.separator + LIB; final File webInfClassesDirectory = new File(webInfClassesDirectoryName); final File webInfLibDirectory = new File(webInfLibDirectoryName); webInfLibDirectory.mkdir(); webInfClassesDirectory.mkdir(); monitor.worked(10); monitor.subTask(TASK_COPYING_FILES); // Copy the Web files. getWebFiles(contextDirectory, webInfDirectory); // Encapsulate the security properties in order to ensure they are valid SecurityCredentials securityCredentials = new SecurityCredentials(properties); if (securityCredentials.hasType(WarDeploymentInfoPanel.BASIC)) { // Replace the variables in the jboss-web.xml file. replaceJBossWebXmlVariables(webInfDirectoryName, securityCredentials.getSecurityRealm()); } // Replace the variables in the web.xml file. replaceWebXmlVariables(webInfDirectoryName, securityCredentials, contextName); // Create properties file and write to classes root. createPropertiesFile(webInfClassesDirectory, properties); // Create and compile Provider files (one per port). createResourceJavaClasses(contextDirectory, webInfLibDirectory, webInfClassesDirectory, properties); monitor.worked(10); monitor.subTask(TASK_CREATING_WAR_ARCHIVE); // ZIP everything in the context directory into the new WAR file. final String warFileName = tempDirectoryName + File.separator + contextName + DOT_WAR; AntTasks.zip(contextDirectoryName, warFileName); monitor.worked(20); // Get the target directory. If it doesn't exist, create it. final String newWarFileDir = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WAR_FILE_SAVE_LOCATION); File newWarDir = new File(newWarFileDir); if (!newWarDir.exists()) { newWarDir.mkdir(); } monitor.subTask(TASK_COPYING_WAR_FILE); // Move the temporary WAR file to its destination. final File warFile = new File(warFileName); final String newWarFileName = getFileName((String)properties.get(WebArchiveBuilderConstants.PROPERTY_WAR_FILE_SAVE_LOCATION), contextName + DOT_WAR); File newWarFile = new File(newWarFileName); if (newWarFile.exists()) { if (!newWarFile.delete()) { String msg = getString("WebArchiveCreationFailed_CouldNotDeleteExistingWARFile"); //$NON-NLS-1$ throw new Exception(msg); } } if (!warFile.renameTo(newWarFile)) { String msg = getString("WebArchiveCreationFailed_CouldNotSaveWARFile"); //$NON-NLS-1$ throw new Exception(msg); } // Delete the temp directory. monitor.subTask(TASK_CLEANUP); tempDir.remove(); monitor.worked(5); } catch (Exception e) { final String msg = getString("WebArchiveCreationFailed"); //$NON-NLS-1$ final IStatus status = new Status(IStatus.ERROR, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_WAR_FILE_CREATION_FAILED, msg, e); // Log the error. WebServicePlugin.Util.log(status); return status; } // Creating the WAR file was successful final String msg = getString("WebArchiveCreationSucceeded"); //$NON-NLS-1$ final IStatus status = new Status(IStatus.OK, WebServicePlugin.PLUGIN_ID, WebArchiveBuilderConstants.STATUS_CODE_WAR_FILE_CREATION_SUCCEEDED, msg, null); return status; } @Override public boolean targetWarFileExists( Properties properties ) { boolean fileExists = false; // Get and validate the context name. final String contextName = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); IStatus status = validateContextName(contextName); if (IStatus.ERROR == status.getSeverity()) { fileExists = true; return fileExists; } final String newWarFileName = getFileName((String)properties.get(WebArchiveBuilderConstants.PROPERTY_WAR_FILE_SAVE_LOCATION), contextName + DOT_WAR); fileExists = (new File(newWarFileName)).exists(); return fileExists; } private static String getString( final String id ) { return WebServicePlugin.Util.getString(I18N_PREFIX + id); } private static String getString( final String id, final Object[] params ) { return WebServicePlugin.Util.getString(I18N_PREFIX + id, params); } /** * This method validates if any of the specified invalid characters are in the input context then a null value will be * returned. Note: the characters are in String format. * * @param contextName * @param chars * @return * @since 7.4 */ private String validateInvalidCharactersInContextName( String contextName, String[] invalidChars ) { int numChars = invalidChars.length; for (int charCounter = 0; charCounter < numChars; charCounter++) { final String invalidChar = invalidChars[charCounter]; if (contextName.indexOf(invalidChar) >= 0) { return invalidChar; } } return null; } /** * Returns a file name for the specified path and name. * * @param path * @param name * @return * @since 7.4 */ private String getFileName( String path, String name ) { String fileName = path; if (!fileName.endsWith(FORWARD_SLASH) && !fileName.endsWith(DOUBLE_BACK_SLASH)) { fileName = fileName + File.separator; } fileName = fileName + name; return fileName; } /** * Copies Web files into the WAR build directory structure. * * @param contextDirectory * @param webInfDirectory * @since 7.4 */ private void getWebFiles( File contextDirectory, File webInfDirectory ) throws Exception { // Copy all of the Web files final String webLibPath = WebServiceLibPlugin.getDefault().getRestWebLibDirectoryPath(); final String webAppsDirectoryName = webLibPath + File.separator + WEBAPPS; final File webAppsDirectory = new File(webAppsDirectoryName); FileUtils.copyRecursively(webAppsDirectory, contextDirectory, null, false); } /** * Replace the variables in the web.xml file with their appropriate values. * * @param webInfDirectoryName * @param properties * @param contextName * @since 8.2 */ private void replaceJBossWebXmlVariables( String webInfDirectoryName, String securityDomain) { // Replace variables in the jboss-web.xml file. File jbossWebXmlFile = new File(webInfDirectoryName + File.separator + JBOSS_WEB_XML); String securityDomainNode = "<security-domain>java:/jaas/" + securityDomain + "</security-domain>"; //$NON-NLS-1$ //$NON-NLS-2$ AntTasks.replace(jbossWebXmlFile, "<!--<security-domain>java:/jaas/teiid-security</security-domain>-->", securityDomainNode); //$NON-NLS-1$ } private String getUrlPatterns() { StringBuilder patternStringBuilder = new StringBuilder(); for (String model:models){ patternStringBuilder.append("<url-pattern>/").append(model).append("/*</url-pattern>").append(NEWLINE); } return patternStringBuilder.toString(); } /** * Replace the variables in the web.xml file with their appropriate values. * * @param webInfDirectoryName * @param properties * @param contextName * * @throws Exception * * @since 7.4 */ private void replaceWebXmlVariables( String webInfDirectoryName, SecurityCredentials securityCredentials, String contextName ) throws Exception { // Replace variables in the web.xml file. webXmlFile = new File(webInfDirectoryName + File.separator + WEB_XML); String urlPatterns = getUrlPatterns(); AntTasks.replace(webXmlFile, "${urlPattern}", urlPatterns); //$NON-NLS-1$ // Update for Basic Auth if HTTPBasic security is selected if (securityCredentials.hasType(WarDeploymentInfoPanel.BASIC)) { AntTasks.replace(webXmlFile, "<!--<security-constraint>", "\t<security-constraint>"); //$NON-NLS-1$ //$NON-NLS-2$ AntTasks.replace(webXmlFile, "${realmName}", securityCredentials.getSecurityRealm()); //$NON-NLS-1$ AntTasks.replace(webXmlFile, "${roleName}", securityCredentials.getSecurityRole()); //$NON-NLS-1$ AntTasks.replace(webXmlFile, "</login-config>-->", "</login-config>"); //$NON-NLS-1$ //$NON-NLS-2$ } AntTasks.replace(webXmlFile, "${warname}", contextName); //$NON-NLS-1$ AntTasks.replace(webXmlFile, "${contextName}", contextName); //$NON-NLS-1$ } /** * Create the teiidrest.properties file. * * @param webInfClassesDirectory * @param properties * @since 7.4 */ private void createPropertiesFile( File webInfClassesDirectory, Properties properties ) throws IOException { // Create teiidrest.properties file File teiidRestProperties = new File(webInfClassesDirectory + File.separator +TEIID_REST_PROPS); String jndiValue = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_JNDI_NAME); if (jndiValue != null && !jndiValue.startsWith(JNDI_PREFIX)) { jndiValue = JNDI_PREFIX + FORWARD_SLASH + jndiValue; } ITeiidServerVersion teiidVersion = ModelerCore.getTeiidServerVersion(); String version = teiidVersion.toString(); FileWriter fstream = null; BufferedWriter out = null; try { // Create file fstream = new FileWriter(teiidRestProperties); out = new BufferedWriter(fstream); out.write(WebArchiveBuilderConstants.PROPERTY_JNDI_NAME + EQUALS + jndiValue + NEWLINE); out.write(WebArchiveBuilderConstants.PROPERTY_TEIID_VERSION + EQUALS + version); } finally { // Close the output stream out.close(); } } /** * Create the Resource (one for each model) and Application java classes * * @param webInfClassesDirectory * @param properties * @throws Exception * @since 7.4 */ private void createResourceJavaClasses( File contextDirectory, File webInfLibDirectory, File webInfClassesDirectory, Properties properties) throws Exception { String pathToResource = "/org" + File.separator + "teiid" + File.separator + "rest" + File.separator + "services"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ String pathToPlugin = "/org" + File.separator + "teiid" + File.separator + "rest"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String teiidProviderJavaFile= null; String vdbFileName = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_VDB_FILE_NAME); String context = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); String vdbName = vdbFileName.substring(vdbFileName.lastIndexOf(File.separator )); vdbName=vdbName.substring(1,vdbName.lastIndexOf(".")) + " VDB"; List<File> resources = new ArrayList<File>(); StringBuilder singletonSb = new StringBuilder(); for (String resource : getModels()) { String resourceJavaFilePath = webInfClassesDirectory.getCanonicalPath() + pathToResource + File.separator + resource + ".java"; //$NON-NLS-1$ FileUtils.copy(webInfClassesDirectory.getCanonicalPath() + pathToResource + File.separator + "ResourceTemplate.java", //$NON-NLS-1$ resourceJavaFilePath, true); File indexHtml = new File(contextDirectory.getCanonicalPath() + File.separator + "index.html"); File resourceJavaFile = new File(resourceJavaFilePath); resources.add(resourceJavaFile); ITeiidServerVersion version = ModelerCore.getTeiidServerVersion(); boolean greaterThan82 = version.isGreaterThan(TeiidServerVersion.Version.TEIID_8_2); if (greaterThan82) { teiidProviderJavaFile = "TeiidRSProviderPost"; //$NON-NLS-1$ }else{ teiidProviderJavaFile = "TeiidRSProviderPre"; //$NON-NLS-1$ } AntTasks.replace(resourceJavaFile, "${TeiidRSProvider}", "org.teiid.rest.services." + teiidProviderJavaFile); //$NON-NLS-1$ //$NON-NLS-2$ AntTasks.replace(resourceJavaFile, "${className}", resource); //$NON-NLS-1$ AntTasks.replace(resourceJavaFile, "${modelName}", "org.teiid.rest.services." + resource); //$NON-NLS-1$ //$NON-NLS-2$ AntTasks.replace(resourceJavaFile, "${path}", "@Path( \"/" + resource + "\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ AntTasks.replace(resourceJavaFile, "${api}", "@Api( value=\"/" + resource + "\", description=\"REST operations\")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String methods = generateMethods(resource); AntTasks.replace(resourceJavaFile, "${httpMethods}", methods); //$NON-NLS-1$ AntTasks.replace(indexHtml, "${title}", vdbName); //$NON-NLS-1$ AntTasks.replace(indexHtml, "${context}", context); //$NON-NLS-1$ AntTasks.replace(indexHtml, "${modelName}", resource); //$NON-NLS-1$ singletonSb.append(NEWLINE + "singletons.add(new org.teiid.rest.services." + resource + "());"); //$NON-NLS-1$ //$NON-NLS-2$ } File template = new File(webInfClassesDirectory.getCanonicalPath() + pathToResource + File.separator + "ResourceTemplate.java"); //$NON-NLS-1$ File restPlugin = new File(webInfClassesDirectory.getCanonicalPath() + pathToPlugin + File.separator + "RestPlugin.java"); //$NON-NLS-1$ File teiidProvider = new File(webInfClassesDirectory.getCanonicalPath() + pathToResource + File.separator + teiidProviderJavaFile + ".java"); //$NON-NLS-1$ File teiidRestApplication = new File(webInfClassesDirectory.getCanonicalPath() + pathToResource + File.separator + "TeiidRestApplication.java"); //$NON-NLS-1$ AntTasks.replace(teiidRestApplication, "${resources}", singletonSb.toString()); //$NON-NLS-1$ template.delete(); String spiPath = DesignerSPIPlugin.getPluginPath(); File spiFile = new File(spiPath); String runtimePath = ModelerCore.getTeiidRuntimePath(); File runtimeFile = new File(runtimePath); // Compile classes JavaCompiler compilerTool = ToolProvider.getSystemJavaCompiler(); if (compilerTool != null) { StandardJavaFileManager fileManager = compilerTool.getStandardFileManager(null, null, null); String pathToJar1 = webInfLibDirectory.getCanonicalPath() + File.separator + JACKSON_CORE_JAR; String pathToJar2 = webInfLibDirectory.getCanonicalPath() + File.separator + JACKSON_JAXRS_JAR; String pathToJar3 = webInfLibDirectory.getCanonicalPath() + File.separator + JSON_JAR; String pathToJar4 = webInfLibDirectory.getCanonicalPath() + File.separator + JAXRS_API_JAR; String pathToJar5 = webInfLibDirectory.getCanonicalPath() + File.separator + SWAGGER_ANNOTATIONS_JAR; String pathToJar6 = webInfLibDirectory.getCanonicalPath() + File.separator + SWAGGER_CORE_JAR; String pathToJar7 = webInfLibDirectory.getCanonicalPath() + File.separator + SWAGGER_JAXRS_JAR; String pathToJar8 = webInfLibDirectory.getCanonicalPath() + File.separator + SERVLET_API; String pathToJar9 = webInfLibDirectory.getCanonicalPath() + File.separator + REFLECTIONS; String pathToJar10 = webInfLibDirectory.getCanonicalPath() + File.separator + SCALA_LIBRARY; String pathToJar11 = webInfLibDirectory.getCanonicalPath() + File.separator + JACKSON_CORE_JAR; String pathToJar12 = webInfLibDirectory.getCanonicalPath() + File.separator + JACKSON_DATABIND_JAR; FileUtils.copy(spiFile, webInfLibDirectory, true); FileUtils.copy(runtimeFile, webInfLibDirectory, true); List<File> classPaths = new ArrayList<File>(); classPaths.add(new File(pathToJar1)); classPaths.add(new File(pathToJar2)); classPaths.add(new File(pathToJar3)); classPaths.add(new File(pathToJar4)); classPaths.add(new File(pathToJar5)); classPaths.add(new File(pathToJar6)); classPaths.add(new File(pathToJar7)); classPaths.add(new File(pathToJar8)); classPaths.add(new File(pathToJar9)); classPaths.add(new File(pathToJar10)); classPaths.add(new File(pathToJar11)); classPaths.add(new File(pathToJar12)); classPaths.add(runtimeFile); classPaths.add(spiFile); fileManager.setLocation(StandardLocation.CLASS_PATH, classPaths); List<File> sourceFileList = new ArrayList<File>(); // prepare the source files to compile for (File resourceClass : resources) { sourceFileList.add(resourceClass); } sourceFileList.add(restPlugin); sourceFileList.add(teiidProvider); sourceFileList.add(teiidRestApplication); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList); /*Create a diagnostic controller, which holds the compilation problems*/ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); ArrayList<String> options = new ArrayList<String>(); CompilationTask task = compilerTool.getTask(null, fileManager, diagnostics, options, null, compilationUnits); task.call(); List<Diagnostic<? extends JavaFileObject>> diagnosticList = diagnostics.getDiagnostics(); for (Diagnostic<? extends JavaFileObject> diagnostic : diagnosticList) { diagnostic.getKind(); if (diagnostic.getKind().equals(Kind.ERROR)) { throw new Exception(diagnostic.getMessage(null)); } } fileManager.close(); Boolean includeJars = (Boolean)properties.get(WebArchiveBuilderConstants.PROPERTY_INCLUDE_RESTEASY_JARS); // Delete RESTEasy and dependent jars if the user elected not to include them. Some jars are required even without // the RESTEasy jars. We will need to save those to a temp folder and then copy them back after removing the RESTEasy jars. if (!includeJars) { File tempFolder = new File(webInfClassesDirectory+"/tmp"); //$NON-NLS-1$ File jsonJar = new File(pathToJar4); // File saxonJar = new File(pathToJar6); List<File> jarsToAdd = new ArrayList<File>(); // jarsToAdd.add(saxonJar); jarsToAdd.add(jsonJar); jarsToAdd.add(spiFile); jarsToAdd.add(runtimeFile); Iterator iter = jarsToAdd.iterator(); while (iter.hasNext()){ FileUtils.copy((File)iter.next(), tempFolder, true); } FileUtils.removeChildrenRecursively(webInfLibDirectory); jarsToAdd = FileUtils.getFilesForPattern(tempFolder.getCanonicalPath(), EMPTY_STRING, ".jar"); //$NON-NLS-1$ iter = jarsToAdd.iterator(); while (iter.hasNext()){ FileUtils.copy((File)iter.next(), webInfLibDirectory, true); } tempFolder.delete(); } } } private String generateMethods( final String name ) { StringBuilder sb = new StringBuilder(); ArrayList procedureList = (ArrayList)modelMapOfProcedures.get(name); Iterator<RestProcedure> procedureIter = procedureList.iterator(); while (procedureIter.hasNext()) { RestProcedure restProcedure = procedureIter.next(); if (restProcedure.getProducesAnnotation() != null && restProcedure.getProducesAnnotation().contains("MediaType.APPLICATION_JSON")) { //$NON-NLS-1$ createJSONMethod(sb, restProcedure); } else { createXMLMethod(sb, restProcedure); } } return sb.toString(); } /** * @param sb * @param restProcedure */ private void createXMLMethod( StringBuilder sb, RestProcedure restProcedure ) { commonRestMethodLogic(sb, restProcedure, "", true); //$NON-NLS-1$ if (restProcedure.getConsumesAnnotation() != null && !restProcedure.getConsumesAnnotation().isEmpty()) { sb.append("\tparameterMap = getInputs(is);" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ } // Gen return and execute sb.append("\treturn teiidProvider.execute(\"" + restProcedure.getFullyQualifiedProcedureName() + "\", parameterMap, \"" + restProcedure.getCharSet() + "\", properties);" + NEWLINE //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-4 + "}" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * @param sb * @param restProcedure */ private void createJSONMethod( StringBuilder sb, RestProcedure restProcedure ) { commonRestMethodLogic(sb, restProcedure, "json", false); //$NON-NLS-1$ if (restProcedure.getConsumesAnnotation() != null && !restProcedure.getConsumesAnnotation().isEmpty()) { sb.append("\tparameterMap = getJSONInputs(is, \""+restProcedure.getCharSet()+ "\");" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } // Gen return and execute sb.append("\tString result = convertStreamToString(teiidProvider.execute(\"" + restProcedure.getFullyQualifiedProcedureName() + "\", parameterMap, \"" + restProcedure.getCharSet() + "\", properties), \"" + restProcedure.getCharSet() + "\");" + NEWLINE //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "\t"); //$NON-NLS-1$ sb.append("\tString json = convertXMLToJSON(result);" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("\treturn json;" + NEWLINE + "\t" + "}" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } /** * @param sb * @param restProcedure */ private void commonRestMethodLogic( StringBuilder sb, RestProcedure restProcedure, String methodAppendString, boolean isXml) { sb.append("@" + restProcedure.getRestMethod().toUpperCase() + NEWLINE + "\t"); //$NON-NLS-1$//$NON-NLS-2$ String uri = methodAppendString == "" ? restProcedure.getUri() : methodAppendString + "/" + restProcedure.getUri(); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("@Path( \"/" + uri + "\" )" + NEWLINE + "\t"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ if (restProcedure.getConsumesAnnotation() != null && !restProcedure.getConsumesAnnotation().isEmpty()) { sb.append(restProcedure.getConsumesAnnotation() + NEWLINE + "\t"); //$NON-NLS-1$ } if (restProcedure.getProducesAnnotation() != null && !restProcedure.getProducesAnnotation().isEmpty()) { sb.append(restProcedure.getProducesAnnotation() + NEWLINE + "\t"); //$NON-NLS-1$ } // Gen method signature if (isXml){ sb.append("@ApiOperation(value=\"(XML) " + restProcedure.getProcedureName() + ": " + restProcedure.getDescription() + "\",response=InputStream.class)" + NEWLINE + "\t"); //$NON-NLS-1$ sb.append("public InputStream " + restProcedure.getProcedureName() + methodAppendString + "( "); //$NON-NLS-1$ //$NON-NLS-2$ }else{ sb.append("@ApiOperation(value=\"(JSON) " + restProcedure.getProcedureName() + ": " + restProcedure.getDescription() + "\",response=String.class)" + NEWLINE + "\t"); sb.append("public String " + restProcedure.getProcedureName() + methodAppendString + "( "); //$NON-NLS-1$ //$NON-NLS-2$ } // Check for URI parameters and add as @PathParams Collection<String> pathParams = WarArchiveUtil.getPathParameters(uri); int pathParamCount = 0; for (String param : pathParams) { pathParamCount++; sb.append("@ApiParam( \"" + param + "\" ) "); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("@PathParam( \"" + param + "\" ) String " + param); //$NON-NLS-1$ //$NON-NLS-2$ if (pathParamCount < pathParams.size()) { sb.append(", "); //$NON-NLS-1$ } } //Now check for header parameters LinkedList<String> headerParamList = new LinkedList<String>(); if (hasHeaders(restProcedure)){ int headerParamCount = 0; headerParamList = restProcedure.getHeaderParameterList(); for (String param : headerParamList) { headerParamCount++; sb.append("@HeaderParam( \"" + param + "\" ) String " + param); //$NON-NLS-1$ //$NON-NLS-2$ if (headerParamCount < headerParamList.size()) { sb.append(", "); //$NON-NLS-1$ } } //Add a comma if we expect to add query parameters in the next block of code if (hasQueryParameters(restProcedure)) sb.append(", "); //$NON-NLS-1$ } //Now check for query parameters LinkedList<String> queryParamList = new LinkedList<String>(); if (pathParamCount==0 && hasQueryParameters(restProcedure)){ int queryParamCount = 0; queryParamList = restProcedure.getQueryParameterList(); for (String param : queryParamList) { queryParamCount++; sb.append("@QueryParam( \"" + param + "\" ) String " + param); //$NON-NLS-1$ //$NON-NLS-2$ if (queryParamCount < queryParamList.size()) { sb.append(", "); //$NON-NLS-1$ } } } if (restProcedure.getConsumesAnnotation() != null && !restProcedure.getConsumesAnnotation().isEmpty()) { if (pathParams.size() > 0 || headerParamList.size() > 0 || queryParamList.size() > 0 ) { sb.append(", "); //$NON-NLS-1$ } sb.append(" InputStream is ) { " + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ } else { sb.append(" ) { " + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ } // Gen setting of parameter(s) sb.append("\tMap<String, String> parameterMap = getParameterMap();" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //We will always consider header parameters first, so the supporting procedure knows the correct order if (headerParamList.size() > 0) { for (String param : headerParamList) { sb.append("\tparameterMap.put(\"" + param + "\", " + param + ");" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } if (pathParams.size() > 0) { for (String param : pathParams) { sb.append("\tparameterMap.put(\"" + param + "\", " + param + ");" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } if (queryParamList.size() > 0) { for (String param : queryParamList) { sb.append("\tparameterMap.put(\"" + param + "\", " + param + ");" + NEWLINE + "\t"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } } /** * @param restProcedure * @return */ private boolean hasQueryParameters(RestProcedure restProcedure) { return restProcedure.getQueryParameterList() != null && restProcedure.getQueryParameterList().size()>0; } /** * @param restProcedure * @return */ private boolean hasHeaders(RestProcedure restProcedure) { return restProcedure.getHeaderParameterList() != null && restProcedure.getHeaderParameterList().size()>0; } class URLValidator implements Serializable { /** */ private static final long serialVersionUID = -4756137226908808631L; public boolean isValidValue( Object value ) { if (value instanceof String) { try { new URL(value.toString()); } catch (MalformedURLException e) { return false; } return true; } else if (value instanceof URL) { return true; } else { return false; } } } /** * @param modelToProcedureMap Map of models with procedures */ public void setModels( Map<String, List<RestProcedure>> modelToProcedureMap ) { Set<String> modelNameSet = modelToProcedureMap.keySet(); this.models = new ArrayList<String>(modelNameSet); } /** * @return models */ public List<String> getModels() { return models; } }