/*******************************************************************************
* 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.eclipse.typelibrary.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.common.config.LibraryType;
import org.ebayopensource.turmeric.common.config.TypeLibraryType;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants.SupportedProjectType;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOATypeLibraryConstants;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.SOAGlobalRegistryAdapter;
import org.ebayopensource.turmeric.eclipse.typelibrary.builders.TypeLibraryProjectNature;
import org.ebayopensource.turmeric.eclipse.utils.io.IOUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil;
import org.ebayopensource.turmeric.tools.library.SOATypeRegistry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDParser;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
/**
* The Class TypeLibraryUtil.
*
* @author smathew
*
* Util class for Type Lib
*/
public class TypeLibraryUtil {
/**
* Gets the xsd file location.
*
* @param typeName the type name
* @param project the project
* @return the xsd file location
* Answers the file location relative to the project structure. In
* short project.getFile() with this output should return the file.
*/
public static String getXsdFileLocation(String typeName, IProject project) {
String retValue = "";
if (!StringUtils.isEmpty(typeName)) {
if (isNewTypLibrary(project)) {
retValue = SOATypeLibraryConstants.FOLDER_META_SRC_TYPES
+ WorkspaceUtil.PATH_SEPERATOR + project.getName()
+ WorkspaceUtil.PATH_SEPERATOR + typeName
+ SOATypeLibraryConstants.EXT_XSD;
} else {
retValue = SOATypeLibraryConstants.FOLDER_META_SRC_TYPES
+ WorkspaceUtil.PATH_SEPERATOR + typeName
+ SOATypeLibraryConstants.EXT_XSD;
}
}
return retValue;
}
/**
* Just appending the extn to the XSD name. Extn names could be changed :)),
* You never know. This is just a dumb helper
*
* @param typeName the type name
* @return the xsd file name from type name
*/
public static String getXsdFileNameFromTypeName(String typeName) {
String retValue = typeName;
if (!StringUtils.isEmpty(typeName)
&& !typeName.endsWith(SOATypeLibraryConstants.EXT_XSD))
retValue = retValue + SOATypeLibraryConstants.EXT_XSD;
return retValue;
}
/**
* Just taking out the extn from the file name. Extn names could be changed
* :)), You never know. This is just a dumb helper
*
* @param fileName the file name
* @return the xsd type name from file name
*/
public static String getXsdTypeNameFromFileName(String fileName) {
String retValue = fileName;
if (!StringUtils.isEmpty(fileName)) {
retValue = StringUtils.substringBeforeLast(fileName,
SOATypeLibraryConstants.EXT_XSD);
}
return retValue;
}
/**
* Adding the TypeLibProtocal to the name for the xsd entry.
*
* @param type the type
* @return the protocol string
*/
public static String getProtocolString(LibraryType type) {
String retValue = null;
if (type != null)
retValue = SOATypeLibraryConstants.TURMERIC_XSD_FILE_PROTOCOL
+ SOATypeLibraryConstants.PROTOCOL_DELIMITER_START
+ type.getLibraryInfo().getLibraryName()
+ SOATypeLibraryConstants.PROTOCOL_DELIMITER
+ getXsdFileNameFromTypeName(type.getName());
return retValue;
}
/**
* Adding the TypeLibProtocal to the name for the xsd entry.
* @param project
* @return
*/
public static IFile getDependencyFile(IProject project) {
return project.getFile(SOATypeLibraryConstants.FOLDER_META_SRC_META_INF
+ WorkspaceUtil.PATH_SEPERATOR + project.getName()
+ WorkspaceUtil.PATH_SEPERATOR
+ SOATypeLibraryConstants.FILE_TYPE_DEP_XML);
}
/**
* Adding the TypeLibProtocal to the name for the xsd entry.
*
* @param typeLibName the type lib name
* @param baseLocation the base location
* @return the dependency stream
* @throws CoreException the core exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public static InputStream getDependencyStream(String typeLibName,
String baseLocation) throws CoreException, IOException {
if (baseLocation.toLowerCase().startsWith("jar:file:/")) {
JarFile jarFile = new JarFile(getJarFile(baseLocation.substring(10,
baseLocation.length())));
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().startsWith(
SOATypeLibraryConstants.INFO_DEP_XML_PATH_IN_JAR)
&& entry.getName().endsWith(
SOATypeLibraryConstants.FILE_TYPE_DEP_XML)) {
return jarFile.getInputStream(entry);
}
}
} else {
IProject project = WorkspaceUtil.getProject(typeLibName);
if (project.isAccessible()
&& project.hasNature(GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getProjectNatureId(
SupportedProjectType.TYPE_LIBRARY))) {
return project.getFile(
SOATypeLibraryConstants.FOLDER_META_SRC_META_INF
+ WorkspaceUtil.PATH_SEPERATOR
+ project.getName()
+ WorkspaceUtil.PATH_SEPERATOR
+ SOATypeLibraryConstants.FILE_TYPE_DEP_XML)
.getContents();
}
}
throw new IOException(
"InpuStream could not be obtained with the type lib Name "
+ typeLibName + " and base location " + baseLocation);
}
/**
* Gets the library type.
*
* @param name the name
* @param version the version
* @param libInfo the lib info
* @return the library type
* @throws Exception the exception
*/
public static LibraryType getLibraryType(String name, String version,
TypeLibraryType libInfo) throws Exception {
SOATypeRegistry typeRegistry = GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getTypeRegistryBridge()
.getSOATypeRegistry();
LibraryType libType = typeRegistry.getType(name, libInfo
.getLibraryName());
if (libType != null) {
return libType;
}
LibraryType libraryType = new LibraryType();
libraryType.setName(name);
libraryType.setVersion(version);
libraryType.setLibraryInfo(libInfo);
return libraryType;
}
/**
* Gets the xSD.
*
* @param libType the lib type
* @return the xSD
* @throws Exception the exception
*/
public static URL getXSD(LibraryType libType) throws Exception {
return getXSD(libType.getLibraryInfo().getLibraryName(), libType
.getName());
}
/**
* Gets the xSD.
*
* @param libraryName the library name
* @param typeName the type name
* @return the xSD
* @throws Exception the exception
*/
public static URL getXSD(String libraryName, String typeName)
throws Exception {
String jarLocation = GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getAssetRegistry()
.getAssetLocation(libraryName);
if (!StringUtils.isEmpty(jarLocation)
&& jarLocation.endsWith(SOAProjectConstants.JAR_EXT)) {
String xsdName = TypeLibraryUtil
.getXsdFileNameFromTypeName(typeName);
URL jarURL = IOUtil.toURL(jarLocation);
String jarEntryPath = "";
if (TypeLibraryUtil.isNewTypLibrary(jarURL, libraryName)) {
jarEntryPath = SOATypeLibraryConstants.TYPES_LOCATION_IN_JAR
+ WorkspaceUtil.PATH_SEPERATOR + libraryName
+ WorkspaceUtil.PATH_SEPERATOR + xsdName;
} else {
jarEntryPath = SOATypeLibraryConstants.TYPES_LOCATION_IN_JAR
+ WorkspaceUtil.PATH_SEPERATOR + xsdName;
}
return IOUtil.getNonLockingURL(jarURL, jarEntryPath);
} else {
IProject project = WorkspaceUtil.getProject(libraryName);
if (project.isAccessible()) {
IFile file = project.getFile(TypeLibraryUtil
.getXsdFileLocation(typeName, project));
return file.getLocation().toFile().toURI().toURL();
}
return null;
}
}
/**
* Gets the type name from protocol string.
*
* @param typeLibString the type lib string
* @return the type name from protocol string
*/
public static String getTypeNameFromProtocolString(String typeLibString) {
String retValue = null;
if (!StringUtils.isEmpty(typeLibString)
&& typeLibString
.startsWith(SOATypeLibraryConstants.TURMERIC_XSD_FILE_PROTOCOL)) {
// removing type lib start string
retValue = StringUtils.substringAfterLast(typeLibString,
SOATypeLibraryConstants.PROTOCOL_DELIMITER);
// removing xsd extn end string
retValue = StringUtils.substringBeforeLast(retValue,
SOATypeLibraryConstants.EXT_XSD);
}
return retValue;
}
/**
* Gets the library name from protocol string.
*
* @param typeLibString the type lib string
* @return the library name from protocol string
*/
public static String getLibraryNameFromProtocolString(String typeLibString) {
String retValue = null;
if (!StringUtils.isEmpty(typeLibString)
&& typeLibString
.startsWith(SOATypeLibraryConstants.TURMERIC_XSD_FILE_PROTOCOL)) {
if (isNewStylePrototocol(typeLibString)) {
retValue = StringUtils.substringBetween(typeLibString,
SOATypeLibraryConstants.PROTOCOL_DELIMITER,
SOATypeLibraryConstants.PROTOCOL_DELIMITER);
}
}
return retValue;
}
private static boolean isNewStylePrototocol(String typeLibString) {
return StringUtils.countMatches(typeLibString,
SOATypeLibraryConstants.PROTOCOL_DELIMITER) == 2;
}
/**
* Gets the type name from xsd schema location.
*
* @param schemaLocation the schema location
* @return the type name from xsd schema location
*/
public static String getTypeNameFromXSDSchemaLocation(String schemaLocation) {
return getXsdTypeNameFromFileName(StringUtils.substringAfterLast(
schemaLocation, "/"));
}
/**
* Creates the library type.
*
* @param typeName the type name
* @return the library type
*/
public static LibraryType createLibraryType(String typeName) {
LibraryType libraryType = GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().getTypeRegistryBridge()
.createLibraryTypeInstance();
libraryType.setName(typeName);
libraryType.setVersion("1.0.0");
return libraryType;
}
/**
* Gets the type information file.
*
* @param project the project
* @return the type information file
*/
public static IFile getTypeInformationFile(IProject project) {
return project
.getFile(SOATypeLibraryConstants.FOLDER_GEN_META_SRC_META_INF
+ WorkspaceUtil.PATH_SEPERATOR + project.getName()
+ WorkspaceUtil.PATH_SEPERATOR
+ SOATypeLibraryConstants.FILE_TYPE_INFO_XML);
}
/**
* Gets the type library type.
*
* @param project the project
* @return the type library type
* @throws CoreException the core exception
*/
public static TypeLibraryType getTypeLibraryType(IProject project)
throws CoreException {
return GlobalRepositorySystem.instanceOf().getActiveRepositorySystem()
.getTypeRegistryBridge().unmarshalTypeInformationType(
getTypeInformationFile(project).getContents());
}
/**
* Gets the all xsd files.
*
* @param project the project
* @param checkExistance the check existance
* @return the all xsd files
* @throws Exception the exception
*/
public static List<IFile> getAllXsdFiles(IProject project,
boolean checkExistance) throws Exception {
List<IFile> files = null;
if (isNewTypLibrary(project)) {
files = WorkspaceUtil
.getFilesWithExtensions(
project
.getFolder(SOATypeLibraryConstants.FOLDER_META_SRC_TYPES
+ WorkspaceUtil.PATH_SEPERATOR
+ project.getName()),
checkExistance, SOATypeLibraryConstants.XSD);
} else {
files = WorkspaceUtil.getFilesWithExtensions(project
.getFolder(SOATypeLibraryConstants.FOLDER_META_SRC_TYPES),
checkExistance, SOATypeLibraryConstants.XSD);
}
return files;
}
/**
* Parses the schema.
*
* @param url the url
* @return the xSD schema
* @throws IOException Signals that an I/O exception has occurred.
*/
public static XSDSchema parseSchema(URL url) throws IOException {
InputStream inputStream = null;
inputStream = url.openStream();
return parseSchema(inputStream);
}
/**
* Parses the schema.
*
* @param inputStream the input stream
* @return the xSD schema
* @throws IOException Signals that an I/O exception has occurred.
*/
public static XSDSchema parseSchema(InputStream inputStream)
throws IOException {
try {
XSDParser xSDParser = new XSDParser();
xSDParser.parse(inputStream);
return xSDParser.getSchema();
} finally {
if (inputStream != null)
IOUtils.closeQuietly(inputStream);
}
}
/**
* Checks if is valid xsd file.
*
* @param fileObject the file object
* @return true, if is valid xsd file
* @throws CoreException the core exception
*/
public static boolean isValidXSDFile(Object fileObject)
throws CoreException {
IFile file = null;
if (fileObject instanceof IFile) {
file = (IFile) fileObject;
}
return file != null
&& file.isAccessible()
&& StringUtils.equalsIgnoreCase(SOATypeLibraryConstants.XSD,
file.getFileExtension())
&& file.getProject() != null
&& file.getProject().isAccessible()
&& file.getProject().hasNature(
TypeLibraryProjectNature.getTypeLibraryNatureId());
}
/**
* Checks if is valid xsd file deleted.
*
* @param fileObject the file object
* @return true, if is valid xsd file deleted
* @throws CoreException the core exception
*/
public static boolean isValidXSDFileDeleted(Object fileObject)
throws CoreException {
IFile file = null;
if (fileObject instanceof IFile) {
file = (IFile) fileObject;
}
return file != null
&& StringUtils.equalsIgnoreCase(SOATypeLibraryConstants.XSD,
file.getFileExtension())
&& !file.exists()
&& file.getProject() != null
&& file.getProject().isAccessible()
&& file.getProject().hasNature(
TypeLibraryProjectNature.getTypeLibraryNatureId());
}
/**
* Checks if is valid xsd file modified.
*
* @param fileObject the file object
* @return true, if is valid xsd file modified
* @throws CoreException the core exception
*/
public static boolean isValidXSDFileModified(Object fileObject)
throws CoreException {
IFile file = null;
if (fileObject instanceof IFile) {
file = (IFile) fileObject;
}
return file != null
&& StringUtils.equalsIgnoreCase(SOATypeLibraryConstants.XSD,
file.getFileExtension())
&& file.exists()
&& file.getProject() != null
&& file.getProject().isAccessible()
&& file.getProject().hasNature(
TypeLibraryProjectNature.getTypeLibraryNatureId());
}
/**
* Gets the project name from wtp base location.
*
* @param baseLocationStr the base location str
* @return the project name from wtp base location
* @throws ParserConfigurationException the parser configuration exception
* @throws SAXException the sAX exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public static String getProjectNameFromWTPBaseLocation(
String baseLocationStr) throws ParserConfigurationException,
SAXException, IOException {
IPath path = new Path(baseLocationStr);
// this is a jar location if base location starts with jar for eg:
// "jar:file:/D:/Views/soapost22/v3jars/services/MarketPlaceServiceCommonTypeLibrary/3.0.0/java50/MarketPlaceServiceCommonTypeLibrary.jar!/types/BaseServiceResponse.xsd"
if (baseLocationStr.toLowerCase().startsWith("jar:file:/")) {
JarFile jarFile = new JarFile(getJarFile(baseLocationStr.substring(
10, baseLocationStr.length())));
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().startsWith(
SOATypeLibraryConstants.INFO_DEP_XML_PATH_IN_JAR)
&& entry.getName().endsWith(
SOATypeLibraryConstants.FILE_TYPE_INFO_XML)) {
return getTypeLibName(entry, jarFile);
}
}
} else {
// New style has the type library name also. So removing an
// additional segment at the end.
if (isNewStyleBaseLocation(baseLocationStr)) {
path = path.removeLastSegments(4);
} else {
// removing meta-src/types/abcd.xsd
path = path.removeLastSegments(3);
}
}
return path.lastSegment();
}
private static File getJarFile(String baseLocation) {
String[] parts = StringUtils.splitByWholeSeparator(baseLocation, "!/");
File file = new File(parts[0]);
return file;
}
private static String getTypeLibName(JarEntry entry, JarFile jarFile)
throws SAXException, IOException, ParserConfigurationException {
String typeLibName = "Lib Not Found";
InputStream stream = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try {
db = dbf.newDocumentBuilder();
stream = jarFile.getInputStream(entry);
Document doc = db.parse(stream);
doc.getDocumentElement().normalize();
typeLibName = doc.getDocumentElement().getAttribute(
SOATypeLibraryConstants.ATTR_TYPE_INFO_LIBNAME);
} catch (ParserConfigurationException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (SAXException e) {
throw e;
} finally {
if (stream != null)
IOUtils.closeQuietly(stream);
}
return typeLibName;
}
/**
* Checks if is new style base location.
*
* @param baseLocationStr the base location str
* @return true, if is new style base location
*/
public static boolean isNewStyleBaseLocation(String baseLocationStr) {
return !(StringUtils.countMatches(
StringUtils.substringAfterLast(baseLocationStr,
SOATypeLibraryConstants.FOLDER_META_SRC_TYPES),
WorkspaceUtil.PATH_SEPERATOR) == 1);
}
/**
* Gets the type name from wtp base location.
*
* @param baseLocationStr the base location str
* @return the type name from wtp base location
*/
public static String getTypeNameFromWTPBaseLocation(String baseLocationStr) {
IPath path = new Path(baseLocationStr);
// removing meta-src/types/abcd.xsd
return getXsdTypeNameFromFileName(path.lastSegment());
}
/**
* To library type.
*
* @param qname the qname
* @return the library type
* @throws Exception the exception
*/
public static LibraryType toLibraryType(QName qname) throws Exception {
return SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry()
.getType(qname);
}
/**
* To q name.
*
* @param libraryType the library type
* @return the q name
* @throws Exception the exception
*/
public static QName toQName(LibraryType libraryType) throws Exception {
return new QName(getNameSpace(libraryType), libraryType.getName());
}
/**
* Gets the name space.
*
* @param libraryType the library type
* @return the name space
*/
public static String getNameSpace(LibraryType libraryType) {
return !StringUtils.isEmpty(libraryType.getNamespace()) ? libraryType
.getNamespace() : libraryType.getLibraryInfo()
.getLibraryNamespace();
}
/**
* Gets the name space.
*
* @param projectName the project name
* @return the name space
* @throws Exception the exception
*/
public static String getNameSpace(String projectName) throws Exception {
return SOAGlobalRegistryAdapter.getInstance().getGlobalRegistry()
.getTypeLibrary(projectName).getLibraryNamespace();
}
/**
* To q name.
*
* @param typeFile the type file
* @return the q name
* @throws Exception the exception
*/
public static QName toQName(IFile typeFile) throws Exception {
String typeLibraryNameSpace = SOAGlobalRegistryAdapter.getInstance()
.getGlobalRegistry().getTypeLibrary(
typeFile.getProject().getName()).getLibraryNamespace();
String typeName = getXsdTypeNameFromFileName(typeFile.getName());
return new QName(typeLibraryNameSpace, typeName);
}
/**
* Old type library project (in workspace) has the dir structure
* meta-src\types\<xsd> and the new one has
* meta-src\types\<typeLibName>\<xsd>.
*
* @param project the project
* @return true, if is new typ library
*/
public static boolean isNewTypLibrary(IProject project) {
return project.getFolder(
SOATypeLibraryConstants.FOLDER_META_SRC_TYPES
+ WorkspaceUtil.PATH_SEPERATOR + project.getName())
.exists();
}
/**
* Old type library jar(NOT in workspace) has the dir structure \types\<xsd>
* and the new one has meta-src\types\<typeLibName>\<xsd>.
*
* @param jarURL the jar url
* @param projectName the project name
* @return true, if is new typ library
* @throws IOException Signals that an I/O exception has occurred.
*/
public static boolean isNewTypLibrary(URL jarURL, String projectName)
throws IOException {
File file = new File(jarURL.getPath());
JarFile jarFile;
jarFile = new JarFile(file);
return jarFile.getEntry(SOATypeLibraryConstants.TYPES_LOCATION_IN_JAR
+ WorkspaceUtil.PATH_SEPERATOR + projectName) != null;
}
/**
* Refresh type dependency in soa type registry.
*
* @param typeLibraryName the type library name
*/
public static void refreshTypeDependencyInSOATypeRegistry(
String typeLibraryName) {
try {
SOAGlobalRegistryAdapter.getInstance()
.refreshTypeDependencyInSOATypeRegistry(typeLibraryName);
} catch (Exception e) {
SOALogger.getLogger().error(e);
}
}
// copied from
// TypeLibraryProjectPropertiesGenerator.TYPE_LIB_PRJ_PROPERTIES_FILE_NAME
/** The Constant TYPE_LIB_PRJ_PROPERTIES_FILE_NAME. */
public static final String TYPE_LIB_PRJ_PROPERTIES_FILE_NAME = "type_library_project.properties";
private static final String COMMENT = "*** Generated file, any changes will be lost upon regeneration ***";
}