/* * 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.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; 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.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xsd.XSDImport; import org.eclipse.xsd.XSDSchema; import org.eclipse.xsd.XSDSchemaContent; import org.eclipse.xsd.util.XSDParser; 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.core.ModelerCore; import org.teiid.designer.core.types.DatatypeConstants; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.runtime.ui.wizards.webservices.WarDeploymentInfoPanel; import org.teiid.designer.ui.util.ErrorHandler; import org.teiid.designer.vdb.ui.util.VdbResourceFinder; import org.teiid.designer.webservice.WebServicePlugin; import org.teiid.designer.webservice.gen.BasicWsdlGenerator; 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 DefaultWebArchiveBuilderImpl implements WebArchiveBuilder, WebServiceLibConstants, StringConstants { private List<String> ports = new ArrayList<String>(); private Map<String, String> operationToProcedureMap = new HashMap<String, String>(); private String wsdlFilename = CoreStringUtil.Constants.EMPTY_STRING; private static final String JNDI_PREFIX = "java:"; //$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_WSDL_FILE = getString("taskCreatingWSDLFile"); //$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$ /** * This constructor is package protected, so that only the factory can call it. * * @since 7.1 */ public DefaultWebArchiveBuilderImpl() { } /** * @param ports Sets ports to the specified value. These names are used for the dynamic generation of servlets in the web.xml, * the jbossws-cxf.xml endpoints and the wsprovider java files. */ public void setPorts( List<String> ports ) { this.ports = ports; } /** * @return ports */ public List<String> getPorts() { return ports; } /** * @return operationToProcedureMap */ public Map<String, String> getOperationToProcedureMap() { return operationToProcedureMap; } /** * @param operationToProcedureMap Sets operationToProcedureMap to the specified value. */ public void setOperationToProcedureMap( Map<String, String> operationToProcedureMap ) { this.operationToProcedureMap = operationToProcedureMap; } @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[] {FORWARD_SLASH , DOUBLE_BACK_SLASH , 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 WebArchiveBuilder#createWebArchive(Properties, IProgressMonitor) * @since 7.1 */ @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()); } // 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.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 images directory. final String imagesDirectoryName = contextDirectoryName + File.separator + IMAGES; final File imagesDirectory = new File(imagesDirectoryName); imagesDirectory.mkdir(); // Create the WEB-INF directory. final String webInfDirectoryName = contextDirectoryName + File.separator + WEB_INF; final File webInfDirectory = new File(webInfDirectoryName); webInfDirectory.mkdir(); // Create the WEB-INF/wsdl directory. final String webInfWsdlDirectoryName = webInfDirectoryName + File.separator + WebServiceLibConstants.WSDL; final File webInfWsdlDirectory = new File(webInfWsdlDirectoryName); webInfWsdlDirectory.mkdir(); // Create the classes directory. final String webInfClassesDirectoryName = webInfDirectoryName + File.separator + CLASSES; // Create the WEB-INF/lib 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_CREATING_WSDL_FILE); // Create WSDL file boolean containsGlobalDataTypes = generateWsdl(properties, webInfWsdlDirectory); monitor.subTask(TASK_COPYING_FILES); // Copy the Web files. getWebFiles(contextDirectory, webInfDirectory, containsGlobalDataTypes); // 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); // Replace the variables in the jbossws-cxf.xml file. replaceJBossWSCXFVariables(webInfDirectoryName, properties, securityCredentials); // Create properties file and write to classes root. createPropertiesFile(webInfClassesDirectory, properties); // Create and compile Provider files (one per port). createProviderJavaClasses(webInfLibDirectory, webInfClassesDirectory, properties, securityCredentials); 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.1 */ 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.1 */ 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.1 */ private void getWebFiles( File contextDirectory, File webInfDirectory, boolean containsGlobalDataTypes) throws Exception { // Copy all of the Web files final String webLibPath = WebServiceLibPlugin.getDefault().getSoapWebLibDirectoryPath(); final String webAppsDirectoryName = webLibPath + File.separator + WEBAPPS; final File webAppsDirectory = new File(webAppsDirectoryName); FileUtils.copyRecursively(webAppsDirectory, contextDirectory, null, false); //Delete builtInDataType.xsd if not applicable to this service if (!containsGlobalDataTypes){ File builtInDataTypeSchemaFile = new File(webInfDirectory.getPath() + "/wsdl/" + DatatypeConstants.DATATYPES_MODEL_FILE_NAME); //$NON-NLS-1$ builtInDataTypeSchemaFile.delete(); } } /** * Replace the variables in the web.xml file with their appropriate values. * * @param webInfDirectoryName * @param properties * @param contextName * * @throws Exception * * @since 7.1 */ private void replaceWebXmlVariables( String webInfDirectoryName, SecurityCredentials securityCredentials, String contextName ) throws Exception { // Replace variables in the web.xml file. File webXmlFile = new File(webInfDirectoryName + File.separator + WEB_XML); // 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$ } else { AntTasks.replace(webXmlFile, "<!--${basic_auth}-->", CoreStringUtil.Constants.EMPTY_STRING); //$NON-NLS-1$ } AntTasks.replace(webXmlFile, "${warname}", contextName); //$NON-NLS-1$ AntTasks.replace(webXmlFile, "${servlets}", createServletTags(getPorts())); //$NON-NLS-1$ } /** * Replace the variables in the web.xml file with their appropriate values. * * @param webInfDirectoryName * @param securityDomain * * @since 7.1 */ 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$ } /** * Replace the variables in the jbossws-cxf.xml file with their appropriate values. * * @param webInfDirectoryName * @param properties * @param securityCredentials * @since 7.1 */ private void replaceJBossWSCXFVariables( String webInfDirectoryName, Properties properties, SecurityCredentials securityCredentials ) { // Replace variables in the jbossws-cxf.xml file. File jbossWSCxfXMLFile = new File(webInfDirectoryName + File.separator + JBOSS_WEB_CXF); AntTasks.replace(jbossWSCxfXMLFile, "${jaxws.endpoint}", createEndpointTags(properties, securityCredentials, getPorts())); //$NON-NLS-1$ if (securityCredentials.hasType(WarDeploymentInfoPanel.WSSE)) { AntTasks.replace(jbossWSCxfXMLFile, "<!--<bean ", "<bean "); //$NON-NLS-1$ //$NON-NLS-2$ AntTasks.replace(jbossWSCxfXMLFile, "</bean>-->", "</bean>"); //$NON-NLS-1$ //$NON-NLS-2$ } } /** * Create the teiidsoap.properties file. * * @param webInfClassesDirectory * @param properties * @since 7.1 */ private void createPropertiesFile( File webInfClassesDirectory, Properties properties ) throws IOException { // Create teiidsoap.properties file File teiisSoapProperties = new File(webInfClassesDirectory + File.separator + TEIID_SOAP_PROPS); String jndiValue = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_JNDI_NAME); if (jndiValue != null && !jndiValue.startsWith(JNDI_PREFIX)) { jndiValue = JNDI_PREFIX + FORWARD_SLASH + jndiValue; } FileWriter fstream = null; BufferedWriter out = null; try { // Create file fstream = new FileWriter(teiisSoapProperties); out = new BufferedWriter(fstream); Iterator it = operationToProcedureMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry)it.next(); out.write(pairs.getKey() + EQUALS + pairs.getValue() + NEW_LINE); } out.write(WebArchiveBuilderConstants.PROPERTY_JNDI_NAME + EQUALS + jndiValue); } finally { // Close the output stream out.close(); } } /** * Create the WSProvider java classes (one for each port) * * @param webInfClassesDirectory * @param properties * @param securityCredentials * @since 7.1 */ private void createProviderJavaClasses( File webInfLibDirectory, File webInfClassesDirectory, Properties properties, SecurityCredentials securityCredentials ) throws Exception { String pathToProviders = "/org" + File.separator + "teiid" + File.separator + "soap" + File.separator + "provider"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ String pathToCallback = "/org" + File.separator + "teiid" + File.separator + "soap" + File.separator + "wsse"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ String pathToPlugin = "/org" + File.separator + "teiid" + File.separator + "soap"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ final String tns = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WSDL_TNS); String context = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); List<File> portProviders = new ArrayList<File>(); for (String port : getPorts()) { String providerJavaFilePath = webInfClassesDirectory.getCanonicalPath() + pathToProviders + File.separator + port + ".java"; //$NON-NLS-1$ FileUtils.copy(webInfClassesDirectory.getCanonicalPath() + pathToProviders + File.separator + "ProviderTemplate.java", //$NON-NLS-1$ providerJavaFilePath, true); File providerJavaFile = new File(providerJavaFilePath); portProviders.add(providerJavaFile); AntTasks.replace(providerJavaFile, "${className}", port); //$NON-NLS-1$ AntTasks.replace(providerJavaFile, "${targetNamespace}", tns); //$NON-NLS-1$ AntTasks.replace(providerJavaFile, "${portName}", port); //$NON-NLS-1$ AntTasks.replace(providerJavaFile, "${serviceName}", context); //$NON-NLS-1$ AntTasks.replace(providerJavaFile, "${wsdlFileName}", this.wsdlFilename); //$NON-NLS-1$ } File template = new File(webInfClassesDirectory.getCanonicalPath() + pathToProviders + File.separator + "ProviderTemplate.java"); //$NON-NLS-1$ File soapPlugin = new File(webInfClassesDirectory.getCanonicalPath() + pathToPlugin + File.separator + "SoapPlugin.java"); //$NON-NLS-1$ File teiidProvider = new File(webInfClassesDirectory.getCanonicalPath() + pathToProviders + File.separator + "TeiidWSProvider.java"); //$NON-NLS-1$ File usernameCallback = new File(webInfClassesDirectory.getCanonicalPath() + pathToCallback + File.separator + "UsernamePasswordCallback.java"); //$NON-NLS-1$ if (securityCredentials.hasType(WarDeploymentInfoPanel.WSSE)) { AntTasks.replace(usernameCallback, "${username}", (String)properties.get(WebArchiveBuilderConstants.PROPERTY_SECURITY_USERNAME)); //$NON-NLS-1$ AntTasks.replace(usernameCallback, "${password}", (String)properties.get(WebArchiveBuilderConstants.PROPERTY_SECURITY_PASSWORD)); //$NON-NLS-1$ } template.delete(); // Compile classes JavaCompiler compilerTool = ToolProvider.getSystemJavaCompiler(); if (compilerTool != null) { StandardJavaFileManager fileManager = compilerTool.getStandardFileManager(null, null, null); String pathToWSSEJar = webInfLibDirectory.getCanonicalPath() + File.separator + "wss4j.jar"; //$NON-NLS-1$ File wsseJar = new File(pathToWSSEJar); List<File> classPaths = Arrays.asList(wsseJar); fileManager.setLocation(StandardLocation.CLASS_PATH, classPaths); // prepare the source files to compile List<File> sourceFileList = new ArrayList<File>(); sourceFileList.add(soapPlugin); sourceFileList.add(teiidProvider); if (securityCredentials.hasType(WarDeploymentInfoPanel.WSSE)) { sourceFileList.add(usernameCallback); } for (File providerClass : portProviders) { sourceFileList.add(providerClass); } Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList); /*Create a diagnostic controller, which holds the compilation problems*/ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); CompilationTask task = compilerTool.getTask(null, fileManager, diagnostics, null, 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(); // Cleanup wsse.jar. Only needed for dynamic compilation. wsseJar.delete(); webInfLibDirectory.delete(); } } private boolean isUseMTOM( Properties properties ) { Object useMotem = properties.get(WebArchiveBuilderConstants.PROPERTY_USE_MTOM); return useMotem == null ? false : useMotem.equals(Boolean.TRUE); } 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 properties * @param webinfWsdlFolder * @return status of wsdl generation * @throws IOException * @throws CoreException */ public boolean generateWsdl( Properties properties, File webinfWsdlFolder) throws IOException, CoreException { BasicWsdlGenerator wsdlGenerator = new BasicWsdlGenerator(); Resource wsModel = null; final String contextName = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); final String host = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WAR_HOST); final String port = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WAR_PORT); final String tns = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WSDL_TNS); String webServiceName = contextName; String vdbFileName = properties.getProperty(WebArchiveBuilderConstants.PROPERTY_VDB_FILE_NAME); IPath vdbPath = new Path(vdbFileName); IFile vdbFile = ModelerCore.getWorkspace().getRoot().getFile(vdbPath); boolean hasGlobalDataType = false; VdbResourceFinder vdbResourceFinder = new VdbResourceFinder(vdbFile); for (Resource webServiceModel : vdbResourceFinder.getWebServiceResources() ) { try { wsModel = webServiceModel; wsdlGenerator.addWebServiceModel(wsModel); ArrayList<Resource> dependentSchemas = new ArrayList<Resource>(); Resource[] resources = vdbResourceFinder.getDependentResources(wsModel); vdbResourceFinder.getAllDependentSchemas(resources, dependentSchemas); for (Resource resource : dependentSchemas) { if (! ModelUtil.isXsdFile(resource)) continue; String fullFilePath = resource.getURI().path(); String fileNameWithExtension = new Path(fullFilePath).lastSegment(); IPath fileLocationPath = new Path(fullFilePath).removeLastSegments(1); // Copy the XSD file to the classes folder XSDSchema xsdSchema = importSchema(fullFilePath); // Check for an import of the global data types schema if (containsGlobalDataTypeImport(xsdSchema)) { hasGlobalDataType = true; // Copy iResource to classesFolder and WEB-INF/wsdl File xsd = new File(fullFilePath); FileUtils.copy(xsd, webinfWsdlFolder, true); // Get handle to new file in wsdl folder File xsdCopy = new File(webinfWsdlFolder.getPath() + FORWARD_SLASH + fileNameWithExtension); // Replace the schemaLocation of the global data // types schema import with the relative path to xsd AntTasks.replace(xsdCopy, "schemaLocation=\"http://www.metamatrix.com/metamodels/SimpleDatatypes-instance\"", //$NON-NLS-1$ "schemaLocation=\"builtInDataTypes.xsd\""); //$NON-NLS-1$ } else { File schemaFile = new File(fullFilePath); FileUtils.copy(schemaFile, webinfWsdlFolder, true); } wsdlGenerator.addXsdModel(xsdSchema, fileLocationPath); } } catch ( Exception e ) { vdbResourceFinder.dispose(); throw ErrorHandler.toCoreException(e); } } vdbResourceFinder.dispose(); wsdlGenerator.setName(webServiceName); wsdlGenerator.setTargetNamespace(tns); wsdlGenerator.setUrlRootForReferences(CoreStringUtil.Constants.EMPTY_STRING); wsdlGenerator.setUrlSuffixForReferences(CoreStringUtil.Constants.EMPTY_STRING); wsdlGenerator.setUrlForWsdlService("http://" + host + ":" + port + FORWARD_SLASH + contextName + FORWARD_SLASH); //$NON-NLS-1$ //$NON-NLS-2$ final IStatus status = wsdlGenerator.generate(new NullProgressMonitor()); // nothing more to do if an error is expected if (status.getSeverity() == IStatus.ERROR) { throw new RuntimeException("Unable to generate WSDL"); //$NON-NLS-1$ } String fileName = webServiceName + ".wsdl"; //$NON-NLS-1$ wsdlFilename = fileName; try { // Create our WSDL file and write to it OutputStream stream = new FileOutputStream(new File(webinfWsdlFolder, fileName)); wsdlGenerator.write(stream); // Get an iFile instance to refresh our workspace IFile iFile = vdbFile; iFile.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); setPorts(wsdlGenerator.getPorts()); setOperationToProcedureMap(wsdlGenerator.getOperationToProcedureMap()); } catch (Exception e) { throw ErrorHandler.toCoreException(e); } return hasGlobalDataType; } private boolean containsGlobalDataTypeImport( final XSDSchema schema ) { boolean containsImport = false; if (schema != null) { final List<XSDSchemaContent> contents = schema.getContents(); for (int i = 0; i < contents.size(); i++) { final Object content = contents.get(i); if (content instanceof XSDImport) { if (DatatypeConstants.BUILTIN_DATATYPES_URI.equals(((XSDImport)content).getNamespace())) { containsImport = true; break; } } } } return containsImport; } private XSDSchema importSchema( String path ) { XSDParser parser = new XSDParser(null); parser.parse(path); XSDSchema schema = parser.getSchema(); schema.setSchemaLocation(path); return schema; } private String createServletTags( List<String> tags ) { StringBuffer servletTags = new StringBuffer(); String startServlet = "\t<servlet>\n"; //$NON-NLS-1$ String endServlet = "\t</servlet>\n"; //$NON-NLS-1$ String startServletName = "\t\t<servlet-name>"; //$NON-NLS-1$ String endServletName = "</servlet-name>\n"; //$NON-NLS-1$ String startServletClass = "\t\t<servlet-class>org.teiid.soap.provider."; //$NON-NLS-1$ String endServletClass = "</servlet-class>\n\t\t<load-on-startup>1</load-on-startup>\n"; //$NON-NLS-1$ String startServletMapping = "\t<servlet-mapping>\n"; //$NON-NLS-1$ String endServletMapping = "\t</servlet-mapping>\n"; //$NON-NLS-1$ String startUrlPattern = "\t\t<url-pattern>/"; //$NON-NLS-1$ String endUrlPattern = "</url-pattern>\n"; //$NON-NLS-1$ for (String port : tags) { servletTags.append(startServlet).append(startServletName).append(port).append(endServletName); servletTags.append(startServletClass).append(port).append(endServletClass).append(endServlet); servletTags.append(startServletMapping).append(startServletName).append(port).append(endServletName); servletTags.append(startUrlPattern).append(port).append(endUrlPattern).append(endServletMapping); } return servletTags.toString(); } private String createEndpointTags( Properties properties, SecurityCredentials securityCredentials, List<String> tags ) { final String contextName = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_CONTEXT_NAME); final String tns = (String)properties.get(WebArchiveBuilderConstants.PROPERTY_WSDL_TNS); StringBuffer endpointTags = new StringBuffer(); String startJaxwsEndpoint = "\t<jaxws:endpoint id="; //$NON-NLS-1$ String endJaxwsEndpoint = "\t</jaxws:endpoint>\n"; //$NON-NLS-1$ String serviceName = " serviceName=\"s:"; //$NON-NLS-1$ String implementor = "\n\t\timplementor=\"org.teiid.soap.provider."; //$NON-NLS-1$ String wsdlLocation = " \n\t\twsdlLocation=\"WEB-INF/wsdl/"; //$NON-NLS-1$ String namespace = " xmlns:s=\""; //$NON-NLS-1$ String wsseInterceptor1 = "\t\t<jaxws:inInterceptors>\n\t\t\t<ref bean=\"UsernameToken_Request\" />\n\t\t\t<bean "; //$NON-NLS-1$ String wsseInterceptor2 = "class=\"org.apache.cxf.binding.soap.saaj.SAAJInInterceptor\" />\n\t\t</jaxws:inInterceptors>\n"; //$NON-NLS-1$ String useMTOM = "\t\t<jaxws:properties>\n\t\t\t<entry key=\"mtom-enabled\" value=\"true\"/>\n\t\t</jaxws:properties>\n"; //$NON-NLS-1$ for (String port : tags) { endpointTags.append(startJaxwsEndpoint).append("\"").append(port).append("\"").append(serviceName); //$NON-NLS-1$ //$NON-NLS-2$ endpointTags.append(contextName).append("\""); //$NON-NLS-1$ endpointTags.append(implementor).append(port).append("\"").append(wsdlLocation).append(wsdlFilename).append("\""); //$NON-NLS-1$ //$NON-NLS-2$ endpointTags.append(namespace).append(tns).append("\">\n"); //$NON-NLS-1$ if (securityCredentials.hasType(WarDeploymentInfoPanel.WSSE)) { endpointTags.append(wsseInterceptor1).append(wsseInterceptor2); } if (isUseMTOM(properties)) { endpointTags.append(useMTOM); } endpointTags.append(endJaxwsEndpoint); } return endpointTags.toString(); } }