/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.tools.library.utils; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.bind.JAXB; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.io.IOUtils; import org.ebayopensource.turmeric.runtime.common.impl.utils.CallTrackingLogger; import org.ebayopensource.turmeric.runtime.common.impl.utils.LogManager; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenConstants; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenUtil; import org.ebayopensource.turmeric.tools.library.TypeLibraryConstants; import org.ebayopensource.turmeric.tools.library.codegen.TypeLibraryCodeGenContext; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import org.ebayopensource.turmeric.common.config.LibraryType; import org.ebayopensource.turmeric.common.config.ReferredType; import org.ebayopensource.turmeric.common.config.ReferredTypeLibraryType; import org.ebayopensource.turmeric.common.config.TypeDependencyType; import org.ebayopensource.turmeric.common.config.TypeLibraryDependencyType; import org.ebayopensource.turmeric.common.config.TypeLibraryType; public class TypeLibraryUtilities { private static CallTrackingLogger logger = LogManager.getInstance(TypeLibraryUtilities.class); private static final String KEY_VALUE_SEPERATOR = "="; private static CallTrackingLogger getLogger(){ return logger; } public static final File[] EMPTY_FILE_ARRAY = new File[0]; public boolean deleteFiles(String fileLocation) { File f = new File(fileLocation); boolean temp = f.delete(); return temp; } /** * Scans a local directory for existing subdirectories. * * @param directory * @param files */ public static List<File> getDirectoryList(File directory) { ArrayList<File> directories = new ArrayList<File>(); File[] filesInDir = directory.listFiles(); for (int i=0; i<filesInDir.length; i++) { File file = filesInDir[i]; if (file.isDirectory()) { directories.add(file); } } return directories; } /** * Scans a local directory for existing files. * * @param directory * @param files */ public static List<String> getFiles(File directory) { ArrayList<String> files = new ArrayList<String>(); File[] filesInDir = directory.listFiles(); for (int i=0; i<filesInDir.length; i++) { File file = filesInDir[i]; if (file.isFile()) { files.add(file.getName()); } } return files; } /** * Deletes everything under a directory (including subdirectories) */ public static List<String> getFiles(String dir) { return getFiles(new File(dir)); } /** * Deletes everything under a directory (including subdirectories) */ public static boolean deleteRecursive(File dir) { if(!dir.exists()) { return true; } File tempFile; File[] fileList = dir.listFiles(); int fileListLength = fileList.length; int index; boolean result = false; // use recursion to go through all the subdirectories and files and delete all of the files for(index = 0; index < fileListLength; index++) { tempFile = fileList[index]; if(tempFile.isDirectory()) { deleteRecursive(tempFile); } else if(tempFile.isFile()) { result = tempFile.delete(); } } // all the files are deleted, so now delete the directory skeleton result= dir.delete(); return result; } /** * Deletes everything under a directory (including subdirectories) */ public static void deleteRecursive(String dir) { deleteRecursive(new File(dir)); } /** * Creates a file or directory * * @param file The file or directory to create * @return true if the file or directory was created; false otherwise */ public static boolean create(String file) { return create(new File(file)); } /** * Creates a file or directory * * @param file The file or directory to create * @return true if the file or directory was created; false otherwise */ public static boolean create(File file) { boolean result; if(isPath(file)) { result = file.mkdirs(); } else { try { result = new File(getPath(file)).mkdirs(); result = file.createNewFile(); } catch (IOException e) { result = false; } } return result; } /** * Determines whether or not a given file name is a path */ public static boolean isPath(File file) { return isPath(file.toString()); } /** * Determines whether or not a given file name is a path * * If the name given exists and */ public static boolean isPath(String file) { if(file.endsWith("/")) { return true; } else { return false; } } /** * Gets the path name for a given file name * * @param file The file name to process * @return The name of the path to the given file */ public static String getPath(File file) { return getPath(file.toString()); } /** * Gets the path name for a given file name * * @param file The file name to process * @return The name of the path to the given file */ public static String getPath(String file) { // return StringUtils.getLeftLast(file, "/") + "/"; return ""; } /** * Creates folder structure for gen-meta-src and gen-src * for TypeLibrary project structure */ public static boolean createProjectSubFolders(TypeLibraryCodeGenContext codeGenCtx) { String projectPath = codeGenCtx.getGenMetaSrcDestFolder(); String genMetaSrc = CodeGenConstants.META_INF_FOLDER + File.separator + codeGenCtx.getLibraryName(); File genMetaSrcFolder = new File(projectPath, genMetaSrc); return genMetaSrcFolder.mkdirs(); } public static String getTypeLibraryProjectName(String projectRootFolder) { String projectName = null; int index = projectRootFolder.lastIndexOf(File.separator); projectName = projectRootFolder.substring(index + 1); return projectName; } public static String getEpisodeFileName(String xsdType){ int index = xsdType.indexOf("."); return xsdType.substring(0, index); } public static String getJavaClassName(String className) { int idx = className.lastIndexOf("."); if (idx <= 0) { return ""; } return className.substring(idx+1); } public static String getTemplateContent(String templateName) throws IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream inputStream = classLoader.getResourceAsStream(templateName); if (inputStream == null) { throw new IOException("Failed to load resource : " + templateName); } String templateContent = readContent(inputStream); return templateContent; } private static String readContent(InputStream input) throws IOException { Charset defaultCharset = Charset.defaultCharset(); StringBuilder strBuff = new StringBuilder(); InputStreamReader isr = null; BufferedReader reader = null; try { isr = new InputStreamReader(input,defaultCharset); reader = new BufferedReader(isr); char[] charBuff = new char[512]; int charsRead = -1; while ((charsRead = reader.read(charBuff)) > -1) { strBuff.append(charBuff, 0, charsRead); } } finally { CodeGenUtil.closeQuietly(reader); CodeGenUtil.closeQuietly(isr); } return strBuff.toString(); } public static File createDir(String dirPath) throws IOException { File dir = null; try { dir = getDir(dirPath); } catch (IOException io) { // Directory doesn't exists dir = new File(dirPath); boolean mkDirSuccess = dir.mkdirs(); if (!mkDirSuccess) { throw new IOException("Failed to create dir(s) : " + dirPath); } } return dir; } public static File getDir(String destDir) throws IOException { if (destDir == null) { return null; } File dir = new File(destDir); if(!dir.exists() || !dir.isDirectory()) { throw new IOException(destDir + ": non-existent directory"); } return dir; } public static String getTypeDepFolder(TypeLibraryCodeGenContext ctx, String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getMetaSrcFolder()).append(File.separator); path.append(TypeLibraryConstants.META_INF_FOLDER).append(File.separator); path.append(libraryName); return path.toString(); } public static String getTypeInfoFolder(TypeLibraryCodeGenContext ctx, String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getGenMetaSrcDestFolder()).append(File.separator); path.append(TypeLibraryConstants.META_INF_FOLDER).append(File.separator); path.append(libraryName); return path.toString(); } public static String getTypesFolder(TypeLibraryCodeGenContext ctx, String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getMetaSrcFolder()).append(File.separator); path.append(TypeLibraryConstants.TYPES_FOLDER); return path.toString(); } public static String getNewTypesFolderLocation(TypeLibraryCodeGenContext ctx,String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getMetaSrcFolder()).append(File.separator); path.append(TypeLibraryConstants.TYPES_FOLDER).append(File.separator); path.append(libraryName); return path.toString(); } public static String getEpisodeFolder(TypeLibraryCodeGenContext ctx, String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getGenMetaSrcDestFolder()).append(File.separator); path.append(TypeLibraryConstants.META_INF_FOLDER).append(File.separator); path.append(libraryName); return path.toString(); } public static String getTypesJavaPropertiesFolder(TypeLibraryCodeGenContext ctx, String libraryName) { StringBuilder path = new StringBuilder(); path.append(ctx.getGenMetaSrcDestFolder()).append(File.separator); path.append(TypeLibraryConstants.META_INF_FOLDER).append(File.separator); path.append(libraryName); return path.toString(); } public static String getGenSrcFolder(TypeLibraryCodeGenContext ctx, String libraryName) { return ctx.getGenJavaSrcDestFolder(); } public static String removePrefix(String input){ String str = input; int index = 0; while((index = str.indexOf(":")) >= 0){ if(index < str.length()) str = str.substring(index+1); else if (index == str.length()) str = str.substring(index); } return str; } public static String[] getFilesInDir(String directory, String fileNameEndsWith) throws Exception{ final String localFilter = fileNameEndsWith; File dir = new File(directory); FilenameFilter filenameFilter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(localFilter); } }; logger.log(Level.INFO,"filenameFilterFiles available "+ dir.list(filenameFilter)); return dir.list(filenameFilter); } public static File[] toFiles(URL[] urls) { if (urls == null || urls.length == 0) { return EMPTY_FILE_ARRAY; } File[] files = new File[urls.length]; for (int i = 0; i < urls.length; i++) { URL url = urls[i]; if (url != null) { if (url.getProtocol().equals("file") == false) { throw new IllegalArgumentException( "URL could not be converted to a File: " + url); } files[i] = toFile(url); } } return files; } public static File toFile(URL url) { if (url == null || !url.getProtocol().equals("file")) { return null; } else { String filename = url.getFile().replace('/', File.separatorChar); int pos =0; while ((pos = filename.indexOf('%', pos)) >= 0) { if (pos + 2 < filename.length()) { String hexStr = filename.substring(pos + 1, pos + 3); char ch = (char) Integer.parseInt(hexStr, 16); filename = filename.substring(0, pos) + ch + filename.substring(pos + 3); } } return new File(filename); } } public static String getSunJaxBEpisodeFolder(TypeLibraryCodeGenContext ctx,String libraryName) { return getEpisodeFolder(ctx,libraryName); } /** * This method validates a version format. It assumes that each part of the version would be a numeric value. * @param input The input String to be verified for version pattern compliance. * @param level The number of major and minor versions etc .. for somethng like 1.0 the level is two , and for something like 1.0.4 the level is 3. * @return */ public static boolean checkVersionFormat(String input,int level){ String patternStr = ""; StringBuffer strBuf = new StringBuffer(); String onePatternStr = "[0-9]+."; for(int i=0; i<level ; i++){ strBuf.append(onePatternStr); } patternStr = strBuf.toString(); patternStr = patternStr.substring(0, patternStr.length()-1); // remove the extra dot at the end Pattern regexPattern = Pattern.compile(patternStr); Matcher regexMatcher = regexPattern.matcher(input); if(regexMatcher.matches()) return true; else return false; } public static boolean isEmptyString(String str) { return (str == null || str.trim().length() == 0); } public static void deleteFile(File file) throws IOException { if (file == null || !file.exists()) { return; } if (!file.delete()) { throw new IOException("Can't delete file : " + file.getPath()); } } /** * Namespace 2 Package algorithm as defined by the JAXB Specification * * @param Namespace * @return String represeting Namespace */ public static String getPackageFromNamespace(String namespace) { //Using the method used by JAXB directly to avoid potential conflicts with JAXB generated code //Therefore commenting out the old code which is based on JAXB 2.0 spec return com.sun.tools.xjc.api.XJC.getDefaultPackageName(namespace); } public static String filterExtensionFromXSDFileName(String xsdTypeName) { String typeName = ""; int index = xsdTypeName.indexOf(".xsd"); if (index < 0) index = xsdTypeName.indexOf(".XSD"); if (index > 0) { typeName = xsdTypeName.substring(0, index); } return typeName; } public static String filterTypeNameFromXSDPath(String xsdSrcPath){ xsdSrcPath = xsdSrcPath.replace("\\", "/"); int index = xsdSrcPath.lastIndexOf("/"); return filterExtensionFromXSDFileName(xsdSrcPath.substring(index+1)); } public static AdditionalXSDInformation parseTheXSDFile(String xsdSrcPath) { final AdditionalXSDInformation additionalXSDInformation = new AdditionalXSDInformation(); class ParseClass extends DefaultHandler { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { String elementName = ("".equals(localName)) ? qName : localName; if (elementName.startsWith("schema") || elementName.contains(":schema")) { String tns = attributes.getValue("targetNamespace"); String version = attributes.getValue("version"); additionalXSDInformation.setTargetNamespace(tns); additionalXSDInformation.setVersion(version); } if (elementName.startsWith("simpleType") || elementName.contains(":simpleType")) { additionalXSDInformation.setSimpleType(true); String typeName = attributes.getValue("name"); additionalXSDInformation.setTypeName(typeName); additionalXSDInformation.getTypeNamesList().add(typeName); } if (elementName.startsWith("complexType") || elementName.contains(":complexType")) { additionalXSDInformation.setSimpleType(false); String typeName = attributes.getValue("name"); additionalXSDInformation.setTypeName(typeName); additionalXSDInformation.getTypeNamesList().add(typeName); } } } File xsdFile = new File(xsdSrcPath); if(!xsdFile.exists()){ //need to do additional check for backward compatibility if(!checkIfXsdExistsInOlderPath(xsdSrcPath,additionalXSDInformation)) { logger.log(Level.INFO,"Xsd file not found in "+ xsdSrcPath); additionalXSDInformation.setDoesFileExist(false); logger.log(Level.INFO,"Setting AdditionalXsdInformation setDoesFileExist to false"); return additionalXSDInformation; } }else{ additionalXSDInformation.setDoesFileExist(true); } DefaultHandler defaultHandler = new ParseClass(); SAXParserFactory parserFactory = SAXParserFactory.newInstance(); if(additionalXSDInformation.isXsdPathChanged()) { String newXsdLocation = getOlderXsdSrcPath(xsdSrcPath); xsdFile = new File(newXsdLocation); } try { SAXParser saxParser = parserFactory.newSAXParser(); saxParser.parse(xsdFile, defaultHandler); } catch (ParserConfigurationException e) { getLogger().log( Level.WARNING, "ParserConfigurationException while parsing XSD file " + xsdSrcPath + "\n" + e.getMessage()); } catch (SAXException e) { getLogger().log( Level.WARNING, "SAXException while parsing XSD file " + xsdSrcPath + "\n" + e.getMessage()); } catch (IOException e) { getLogger().log( Level.WARNING, "IOException while parsing XSD file " + xsdSrcPath + "\n" + e.getMessage()); } return additionalXSDInformation; } /* * This method checks if xsd files are present in the older structure. */ private static boolean checkIfXsdExistsInOlderPath(String newXsdPath, AdditionalXSDInformation additionalInfo) { String oldXsdLocation = getOlderXsdSrcPath(newXsdPath); File xsdFileinOldPath = new File(oldXsdLocation); if (xsdFileinOldPath.exists()) { logger.log(Level.INFO, "Found xsd file in "+oldXsdLocation); additionalInfo.setXsdPathChanged(true); additionalInfo.setDoesFileExist(true); return true; } else { logger.log(Level.INFO, " xsd file not present in older path "); return false; } } /* * This method is written to support backward compatibility for typeLibrary. * returns the older structure of xsd files. */ public static String getOlderXsdSrcPath(String newXsdPath) { String osIndepedentPath = normalizeFilePath(newXsdPath); int indexForSeperator = osIndepedentPath.lastIndexOf(File.separatorChar); String xsdTypeName = osIndepedentPath.substring(indexForSeperator+1); int typesIndex = osIndepedentPath.substring(0,indexForSeperator).lastIndexOf(File.separatorChar); String olderPath = osIndepedentPath.substring(0, typesIndex); String olderXsdsrcPath = olderPath + File.separator + xsdTypeName ; return olderXsdsrcPath; } /** * Returns the content of the input file as a String * * @param file * @return */ public static String getContentFromFile(File file) { StringBuilder stringBuilder = new StringBuilder(); BufferedReader br = null; try { br = new BufferedReader(new FileReader(file)); String lineContent = null; while((lineContent = br.readLine()) != null){ stringBuilder.append(lineContent).append("\n"); } } catch (FileNotFoundException e) { getLogger().log(Level.WARNING, e.getMessage()); } catch (IOException e) { getLogger().log(Level.WARNING, e.getMessage()); }finally{ CodeGenUtil.closeQuietly(br); } return stringBuilder.toString(); } public static String getContentFromSunEpisodeForMasterEpisode(InputStream inputStream, boolean isFirstFile) throws IOException{ Charset defaultCharset = Charset.defaultCharset(); InputStreamReader isr = null; BufferedReader reader = null; StringBuffer strBuff = new StringBuffer(); String lineStr = ""; boolean startOfContentReached = false; try{ isr = new InputStreamReader(inputStream,defaultCharset); reader = new BufferedReader(isr); while( (lineStr = reader.readLine()) != null){ if(lineStr.trim().contains(TypeLibraryConstants.MASTER_EPISODE_TURMERIC_START_COMMNENT)){ startOfContentReached = true; if(! isFirstFile){ // if this sun-jaxb.episode file is not the first episode file then we will have to skip two more lines reader.readLine(); reader.readLine(); } break; } } if(startOfContentReached){ while( (lineStr = reader.readLine()) != null){ if(lineStr.trim().contains(TypeLibraryConstants.MASTER_EPISODE_TURMERIC_END_COMMNENT)){ int index = strBuff.lastIndexOf("</bindings>"); if(index > 0) strBuff = new StringBuffer(strBuff.substring(0,index)); break; } strBuff.append(lineStr + "\n"); } } }finally{ CodeGenUtil.closeQuietly(reader); CodeGenUtil.closeQuietly(isr); } return strBuff.toString(); } public static String normalizePath(String path) { if (path == null) { return null; } if (path.endsWith("\\") || path.endsWith("/")) { return path; } else { return path + File.separatorChar; } } public static String toOSFilePath(String path) { if (path == null) { return null; } String normaliedOSPath = path.replace('\\', File.separatorChar) .replace('/', File.separatorChar); return normalizePath(normaliedOSPath); } public static String normalizeFilePath(String filePath){ if (filePath == null) { return null; } String normaliedOSFilePath = filePath.replace('\\', File.separatorChar) .replace('/', File.separatorChar); return normaliedOSFilePath; } public static OutputStream getFileOutputStream( String destDir, String fileName) throws IOException { if (isEmptyString(destDir) || isEmptyString(fileName)) { return null; } File dir = createDir(destDir); File outputFile = new File(dir, fileName); // delete previous file, if exists deleteFile(outputFile); FileOutputStream fileOutStream = new FileOutputStream(outputFile); return fileOutStream; } /** * @deprecated use {@link CodeGenUtil#closeQuietly(Closeable)} instead. */ @Deprecated public static void closeOutputStream(OutputStream outputStream) { CodeGenUtil.closeQuietly(outputStream); } public static Properties getPropertiesFromFile(String propertiesFilePath) { Properties properties = new Properties(); File file = new File(propertiesFilePath); if(!file.exists()) return properties; InputStream inputStream = null; try { inputStream = new FileInputStream(file); properties.load(inputStream); } catch (FileNotFoundException e) { getLogger().log(Level.WARNING, "Could not open input stream for properties file " + propertiesFilePath); } catch (IOException e) { getLogger().log(Level.WARNING, "Could not open input stream for properties file " + propertiesFilePath); } finally{ CodeGenUtil.closeQuietly(inputStream); } return properties; } public static Set<String> convertSetOfObjectsToSetOfStrings(Set<Object> setOfObjects){ Set<String> setOfStrings = new HashSet<String>(setOfObjects.size()); for(Object object : setOfObjects) setOfStrings.add(object.toString()); return setOfStrings; } /** * * @param propertiesFileRelativePath * @param classLoader * @return a Properties which represents the properties file */ public static Properties getPropertiesFromFileFromClassPath(String propertiesFileRelativePath,ClassLoader classLoader) { Properties properties = new Properties(); InputStream inputStream = getInputStreamForAFileFromClasspath(propertiesFileRelativePath,classLoader); if(inputStream != null){ try { properties.load(inputStream); } catch (IOException e) { getLogger().log(Level.WARNING, "Could not get properties file : " + propertiesFileRelativePath + "\n Exception is :" + e.getMessage()); } } return properties; } public static String getTypeNameFromFileName(String xsdFileName){ String result= xsdFileName; if (!CodeGenUtil.isEmptyString(xsdFileName)) { int index = xsdFileName.indexOf(".xsd"); if (index < 0) index = xsdFileName.indexOf(".XSD"); if (index > 0) { result = xsdFileName.substring(0, index); } } return result; } public static QName getQNameOfLibraryType(LibraryType libraryType){ return new QName(libraryType.getNamespace(),libraryType.getName()); } @Deprecated public static Set<String> findDependentLibrariesForAType(TypeLibraryCodeGenContext ctx, String typeLibraryName,String typeName) throws Exception { getLogger().log(Level.INFO, "Input params for findDependentLibrariesForAType \n" + "projectRoot :" +ctx.getProjectRoot() +"\n" + "typelibrary name :" + typeLibraryName + "\n" + "typeName :" + typeName); Set<String> depLibraryNames = new HashSet<String>(); TypeLibraryDependencyType typeLibraryDependencyType = null; if(!ctx.isProjectRootBlank()){ String typeDefsFolder = TypeLibraryUtilities.getTypeDepFolder(ctx, typeLibraryName ); File typeDepFile = new File(typeDefsFolder + File.separator + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME); if(!typeDepFile.exists()) return depLibraryNames; //Its not mandatory for a project to have TypeDependencies.xml file FileInputStream fis = null; try { fis = new FileInputStream(typeDepFile); typeLibraryDependencyType = JAXB.unmarshal(fis, TypeLibraryDependencyType.class); } catch(IOException e) { getLogger().log(Level.WARNING, "Could not find the " + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME + " for the library "+ typeLibraryName + " in the method findDependentLibrariesForAType in TypeLibraryUtilities , \n the file was searched at location " + typeDepFile.getAbsolutePath(), e); return depLibraryNames; } finally { IOUtils.closeQuietly(fis); } } if(typeLibraryDependencyType == null) typeLibraryDependencyType = getTypeLibraryDependencyTypeForLibrary(typeLibraryName); getLogger().log(Level.INFO, "Calling function findDependantLibrariesRecursivelyAtInvidualTypeLevel for type : " + typeName); ProcessedType typeToBeProcessed = new ProcessedType(typeName,typeLibraryName); Set<ProcessedType> processedTypes = new HashSet<ProcessedType>(); findDependantLibrariesRecursivelyAtIndividualTypeLevel( typeLibraryDependencyType, typeToBeProcessed, depLibraryNames, processedTypes ); getLogger().exiting(); return depLibraryNames; } @Deprecated private static void findDependantLibrariesRecursivelyAtIndividualTypeLevel(TypeLibraryDependencyType typeLibraryDependencyType, ProcessedType inputProcessType, Set<String> depLibrariesName, Set<ProcessedType> processedTypes) throws Exception { getLogger().entering(new Object[]{typeLibraryDependencyType,inputProcessType,depLibrariesName,processedTypes}); if(typeLibraryDependencyType == null) return; if ( ! processedTypes.add(inputProcessType)) return; // type already processed, so return. this is necessary to avoid cyclic dependency related issues TypeDependencyType currTypesTypeDependencyType = null; for(TypeDependencyType typeDependencyType : typeLibraryDependencyType.getType()){ if(typeDependencyType.getName().equals(inputProcessType.getTypeName())){ currTypesTypeDependencyType = typeDependencyType; break; } } if(currTypesTypeDependencyType == null) return; //This type does not have any dependency and hence return. for(ReferredTypeLibraryType referredTypeLibraryType : currTypesTypeDependencyType.getReferredTypeLibrary()){ String currReferredLibraryName = referredTypeLibraryType.getName(); depLibrariesName.add( currReferredLibraryName ); TypeLibraryDependencyType currRefTypeLibraryDependencyType = getTypeLibraryDependencyTypeForLibrary(referredTypeLibraryType.getName()); if(currRefTypeLibraryDependencyType == null) return; for(ReferredType currReferredType : referredTypeLibraryType.getReferredType()){ depLibrariesName.add(currReferredLibraryName); ProcessedType currTypeToBeProcessed = new ProcessedType(currReferredType.getName(),currReferredLibraryName); getLogger().log(Level.INFO, "Calling function findDependantLibrariesRecursivelyAtInvidualTypeLevel for type : " + currTypeToBeProcessed.getTypeName()); findDependantLibrariesRecursivelyAtIndividualTypeLevel(currRefTypeLibraryDependencyType, currTypeToBeProcessed, depLibrariesName, processedTypes); } } } private static TypeLibraryDependencyType getTypeLibraryDependencyTypeForLibrary(String libraryName) { getLogger().log(Level.INFO, "Entering method getTypeLibraryDependencyTypeForLibrary for : " + libraryName); String defaultTypeDepFilePath = TypeLibraryConstants.META_INF_FOLDER + "/" + libraryName + "/" + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME; ClassLoader myClassLoader = TypeLibraryUtilities.class.getClassLoader(); InputStream inStream = null; try { inStream = myClassLoader.getResourceAsStream(defaultTypeDepFilePath); if(inStream == null){ getLogger().log(Level.WARNING, "Could not find the " + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME + " for the library "+ libraryName + " using the first classloader " + myClassLoader); myClassLoader = Thread.currentThread().getContextClassLoader(); inStream = myClassLoader.getResourceAsStream(defaultTypeDepFilePath); } if(inStream == null) { getLogger().log(Level.WARNING, "Could not find the " + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME + " for the library "+ libraryName + " in the method getTypeLibraryDependencyTypeForLibrary in TypeLibraryUtilities using classloader "+ myClassLoader); return null; } getLogger().log(Level.INFO, "Found the " + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME + " for the library "+ libraryName + " in the method getTypeLibraryDependencyTypeForLibrary in TypeLibraryUtilities using classloader "+ myClassLoader + "\n"+ "The path used was : " + defaultTypeDepFilePath); TypeLibraryDependencyType typeLibraryDependencyType = JAXB.unmarshal(inStream, TypeLibraryDependencyType.class); return typeLibraryDependencyType; } finally { CodeGenUtil.closeQuietly(inStream); } } private static class ProcessedType{ private String typeName; private String libraryName; public ProcessedType(String typeName, String libraryName) { super(); this.typeName = typeName; this.libraryName = libraryName; } @SuppressWarnings("unused") public String getLibraryName() { return libraryName; } public String getTypeName() { return typeName; } @Override public int hashCode() { final int PRIME = 31; int result = 1; result = PRIME * result + ((libraryName == null) ? 0 : libraryName.hashCode()); result = PRIME * result + ((typeName == null) ? 0 : typeName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final ProcessedType other = (ProcessedType) obj; if (libraryName == null) { if (other.libraryName != null) return false; } else if (!libraryName.equals(other.libraryName)) return false; if (typeName == null) { if (other.typeName != null) return false; } else if (!typeName.equals(other.typeName)) return false; return true; } @Override public String toString() { return "Type Name = " + typeName + " : " + "Library Name = " + libraryName ; } } /** * Tries to get the input stream using the classloader used for the loading the class passed as input param. If not found * then it tries to load the file from the current Threads context classloader * @param relativeFilePath * @param parentClassLoader (optional) * @return */ public static InputStream getInputStreamForAFileFromClasspath(String relativeFilePath, ClassLoader parentClassLoader ){ relativeFilePath = TypeLibraryUtilities.normalizeFilePath(relativeFilePath); relativeFilePath = relativeFilePath.replace("\\", "/"); getLogger().log(Level.INFO, "call to getInputStreamForAFileFromClasspath for path : " + relativeFilePath); InputStream inStream = null; if(parentClassLoader != null) inStream = parentClassLoader.getResourceAsStream(relativeFilePath); if(inStream == null){ ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader(); inStream = myClassLoader.getResourceAsStream(relativeFilePath); } if(inStream == null) inStream = TypeLibraryUtilities.class.getClassLoader().getResourceAsStream(relativeFilePath); if(inStream == null) getLogger().log(Level.WARNING, "Could not find the file from classpath : " + relativeFilePath + " in the method getInputStreamForAFileFromClasspath"); else getLogger().log(Level.INFO, "Found the file from classpath : " + relativeFilePath + " in the method getInputStreamForAFileFromClasspath"); return inStream; } /** * * @param libraryNames list of library names for which the namespace information has to be derived. * @param projectRoot optional - If passed, the TypeInformation.xml file would be looked under this folder first. Only if not found the claasloaders * would be used to find the TypeInformaion.xml file * @param parentClassLoader optional - If passed this classloaded would be used to locate the TypeInformation.xml file * before trying to make use of the context class loader. * @return */ public static Map<String,String> getLibrariesNameSpace(List<String> libraryNames,TypeLibraryCodeGenContext ctx,ClassLoader parentClassLoader) { Map<String, String> libNSMap = new HashMap<String, String>(libraryNames.size()); for(String currLibraryName : libraryNames){ InputStream inputStream = null; try { String nameSpace= null; if(ctx != null && !ctx.isProjectRootBlank()){ String typeInformationFilePath = TypeLibraryUtilities.getTypeInfoFolder(ctx, currLibraryName) ; typeInformationFilePath = normalizePath(typeInformationFilePath) + TypeLibraryConstants.TYPE_INFORMATION_FILE_NAME; File typeInfoFile = new File(typeInformationFilePath); if(typeInfoFile.exists()) { try { inputStream = new FileInputStream(typeInfoFile); } catch (FileNotFoundException e) { getLogger().log(Level.WARNING, "Exception while getting file from path " + typeInfoFile.getAbsolutePath()); } } } if(inputStream == null){ String typeInfoFileRelativePath = getTypeInformationFileRelativePath(currLibraryName); inputStream = getInputStreamForAFileFromClasspath(typeInfoFileRelativePath,parentClassLoader); } if(inputStream != null){ TypeLibraryType typeLibraryType = JAXB.unmarshal(inputStream, TypeLibraryType.class); if(typeLibraryType != null){ nameSpace = typeLibraryType.getLibraryNamespace(); } libNSMap.put(currLibraryName, nameSpace); } } finally { CodeGenUtil.closeQuietly(inputStream); } } return libNSMap; } public static String getTypeInformationFileRelativePath(String libraryName){ String path = normalizePath(TypeLibraryConstants.META_INF_FOLDER ) + libraryName; path = normalizePath(path) + TypeLibraryConstants.TYPE_INFORMATION_FILE_NAME; return path.replace("\\", "/"); } public static Map<String,Set<String>> findDependentLibrariesAndTypesForAType(TypeLibraryCodeGenContext ctx, String typeLibraryName,String typeName) throws Exception { getLogger().log(Level.INFO, "Input params for findDependentLibrariesForAType \n" + "projectRoot :" +ctx.getProjectRoot() +"\n" + "typelibrary name :" + typeLibraryName + "\n" + "typeName :" + typeName); Map<String,Set<String>> depLibraryAndTypeNamesMap = new HashMap<String, Set<String>>(); TypeLibraryDependencyType typeLibraryDependencyType = null; if(!ctx.isProjectRootBlank()){ String typeDefsFolder = TypeLibraryUtilities.getTypeDepFolder(ctx, typeLibraryName ); File typeDepFile = new File(typeDefsFolder + File.separator + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME); if(!typeDepFile.exists()) return depLibraryAndTypeNamesMap; //Its not mandatory for a project to have TypeDependencies.xml file FileInputStream fis = null; try { fis = new FileInputStream(typeDepFile); typeLibraryDependencyType = JAXB.unmarshal(fis, TypeLibraryDependencyType.class); } catch(IOException e) { getLogger().log(Level.WARNING, "Could not find the " + TypeLibraryConstants.TYPE_DEPENDENCIES_FILE_NAME + " for the library "+ typeLibraryName + " in the method findDependentLibrariesAndTypesForAType in TypeLibraryUtilities , \n the file was searched at location " + typeDepFile.getAbsolutePath(), e); return depLibraryAndTypeNamesMap; } finally { IOUtils.closeQuietly(fis); } } if(typeLibraryDependencyType == null) typeLibraryDependencyType = getTypeLibraryDependencyTypeForLibrary(typeLibraryName); getLogger().log(Level.INFO, "Calling function findDependantLibrariesRecursivelyAtInvidualTypeLevel for type : " + typeName); ProcessedType typeToBeProcessed = new ProcessedType(typeName,typeLibraryName); Set<ProcessedType> processedTypes = new HashSet<ProcessedType>(); findDependantLibrariesAndTypesRecursivelyAtIndividualTypeLevel( typeLibraryDependencyType, typeToBeProcessed, depLibraryAndTypeNamesMap, processedTypes ); return depLibraryAndTypeNamesMap; } private static void findDependantLibrariesAndTypesRecursivelyAtIndividualTypeLevel(TypeLibraryDependencyType typeLibraryDependencyType, ProcessedType inputProcessType, Map<String, Set<String>> depLibraryAndTypeNamesMap, Set<ProcessedType> processedTypes) throws Exception { getLogger().entering(new Object[]{typeLibraryDependencyType,inputProcessType,depLibraryAndTypeNamesMap,processedTypes}); if(typeLibraryDependencyType == null) return; if ( ! processedTypes.add(inputProcessType)) return; // type already processed, so return. this is necessary to avoid cyclic dependency related issues TypeDependencyType currTypesTypeDependencyType = null; for(TypeDependencyType typeDependencyType : typeLibraryDependencyType.getType()){ if(typeDependencyType.getName().equals(inputProcessType.getTypeName())){ currTypesTypeDependencyType = typeDependencyType; break; } } if(currTypesTypeDependencyType == null) return; //This type does not have any dependency and hence return. for(ReferredTypeLibraryType referredTypeLibraryType : currTypesTypeDependencyType.getReferredTypeLibrary()){ String currReferredLibraryName = referredTypeLibraryType.getName(); TypeLibraryDependencyType currRefTypeLibraryDependencyType = getTypeLibraryDependencyTypeForLibrary(currReferredLibraryName); if(currRefTypeLibraryDependencyType == null) return; for(ReferredType currReferredType : referredTypeLibraryType.getReferredType()){ Set<String> listOfTypesFromCurrLibrary = depLibraryAndTypeNamesMap.get(currReferredLibraryName); if(listOfTypesFromCurrLibrary == null) listOfTypesFromCurrLibrary = new HashSet<String>(); listOfTypesFromCurrLibrary.add(currReferredType.getName()); if(!depLibraryAndTypeNamesMap.containsKey(currReferredLibraryName)) // the map does not yet have the entry for this library, so use the put method depLibraryAndTypeNamesMap.put(currReferredLibraryName, listOfTypesFromCurrLibrary); ProcessedType currTypeToBeProcessed = new ProcessedType(currReferredType.getName(),currReferredLibraryName); getLogger().log(Level.INFO, "Calling function findDependantLibrariesRecursivelyAtInvidualTypeLevel for type : " + currTypeToBeProcessed.getTypeName()); findDependantLibrariesAndTypesRecursivelyAtIndividualTypeLevel(currRefTypeLibraryDependencyType, currTypeToBeProcessed, depLibraryAndTypeNamesMap, processedTypes); } } } public static String getStringContentFromProperties(Properties properties){ StringBuilder serviceOpsStrBuilder = new StringBuilder(); serviceOpsStrBuilder.append("#*** Generated file, any changes will be lost upon regeneration ***").append("\n"); // generates: // key1=value1 // key2=value2 // etc.. like property file contents for (Map.Entry<Object, Object> serviceOpsEntry : properties.entrySet()) { serviceOpsStrBuilder.append(serviceOpsEntry.getKey().toString()) .append(KEY_VALUE_SEPERATOR) .append(serviceOpsEntry.getValue().toString()) .append("\r\n"); } return serviceOpsStrBuilder.toString(); } public static String[] getXsdPresentInolderPath(TypeLibraryCodeGenContext ctx, String libraryName) throws Exception { String oldTypesrcPath = TypeLibraryUtilities.getTypesFolder(ctx, libraryName); String[]xsdTypes = TypeLibraryUtilities.getFilesInDir(oldTypesrcPath, ".xsd"); return xsdTypes; } }