/******************************************************************************* * 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.buildsystem; import java.io.InputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; 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.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; import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOATypeLibraryConstants; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.ITypeRegistryBridge; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.SOAGlobalRegistryAdapter; import org.ebayopensource.turmeric.eclipse.typelibrary.resources.model.SOATypeLibraryProject; 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.IProgressMonitor; /** * Marshaller and Unmarshaller for type dependency xml. Additionally this * contains helper method for modeling the xml. Parsing, Saving, Modifying * helper methods are provided here * * @author smathew */ public class TypeDepMarshaller { /** * Wrapper Method. Extract the project, library name and version from the * parameter model and call the * * @param typeLibraryProject - * Extracts the project name, version etc from this object * @param monitor the monitor * @throws CoreException the core exception * @throws JAXBException the jAXB exception * @see {@link TypeDepMarshaller#createDefaultDepXml(IProject project, * String libraryName, String version, IProgressMonitor monitor)} * * method. */ public static void createDefaultDepXml( SOATypeLibraryProject typeLibraryProject, IProgressMonitor monitor) throws CoreException, JAXBException { IProject project = typeLibraryProject.getEclipseMetadata().getProject(); String libName = typeLibraryProject.getTypeLibraryMetadata().getName(); String version = typeLibraryProject.getTypeLibraryMetadata() .getVersion(); createDefaultDepXml(project, libName, version, monitor); } /** * Wrapper Method. Library name is the project name itself. Version is taken * from the constants file * * @param project the project * @param monitor the monitor * @throws CoreException the core exception * @throws JAXBException the jAXB exception * @see {@link TypeDepMarshaller#createDefaultDepXml(IProject project, * String libraryName, String version, IProgressMonitor monitor)} * * method. */ public static void createDefaultDepXml(IProject project, IProgressMonitor monitor) throws CoreException, JAXBException { createDefaultDepXml(project, project.getName(), SOATypeLibraryConstants.DEFAULT_TYPE_DEP_VERSION, monitor); } private static void createDefaultDepXml(IProject project, String libraryName, String version, IProgressMonitor monitor) throws CoreException, JAXBException { // creates the empty file IFile file = WorkspaceUtil.createEmptyFile(project, SOATypeLibraryConstants.FOLDER_META_SRC_META_INF + WorkspaceUtil.PATH_SEPERATOR + project.getName() + WorkspaceUtil.PATH_SEPERATOR + SOATypeLibraryConstants.FILE_TYPE_DEP_XML, monitor); WorkspaceUtil.refresh(file); ITypeRegistryBridge birdge = GlobalRepositorySystem.instanceOf() .getActiveRepositorySystem().getTypeRegistryBridge(); TypeLibraryDependencyType typeLibraryDependencyType = birdge .createTypeLibraryDependencyTypeInstance(); typeLibraryDependencyType.setLibraryName(libraryName); typeLibraryDependencyType.setVersion(version); marshallIt(typeLibraryDependencyType, file); WorkspaceUtil.refresh(file); } /** * Finds the type entry under the parameter type library dependency type * with the specified type name and pass it back. Returns null if not found. * Remember typeLibraryDependencyType is the root tag in the xml. So this * API returns the first level type in the xml. to be precise the first * level types refers to some other types, They are the referree(the one who * refers to) * * @param typeLibraryDependencyType the type library dependency type * @param typeName the type name * @return the type entry */ public static TypeDependencyType getTypeEntry( TypeLibraryDependencyType typeLibraryDependencyType, String typeName) { for (TypeDependencyType type : typeLibraryDependencyType.getType()) { if (StringUtils.equals(typeName, type.getName())) { return type; } } return null; } /** * Adds an type entry only if it does not exist. Its No operation otherwise. * Returns true only if it is modified. Remember the return factor does NOT * indicate the presence of this type. * * @param typeLibraryDependencyType the type library dependency type * @param libraryType the library type * @return true, if successful */ public static boolean addTypeEntryIfNotExists( TypeLibraryDependencyType typeLibraryDependencyType, LibraryType libraryType) { if (getTypeEntry(typeLibraryDependencyType, libraryType.getName()) == null) { addTypeEntry(libraryType, typeLibraryDependencyType); return true; } return false; } /** * Modifies only the version(for now) of the type entry if it exists and the * existing version is not the same. Its No operation otherwise. Returns * true only if it there was a modification. Remember the return factor does * NOT indicate the presence of this type. * * @param typeLibraryDependencyType the type library dependency type * @param libraryType the library type * @return true, if successful */ public static boolean modifyTypeEntry( TypeLibraryDependencyType typeLibraryDependencyType, LibraryType libraryType) { TypeDependencyType typeDependencyType = getTypeEntry( typeLibraryDependencyType, libraryType.getName()); if (typeDependencyType != null && !StringUtils.equals(libraryType.getVersion(), typeDependencyType.getVersion())) { typeDependencyType.setVersion(libraryType.getVersion()); return true; } return false; } /** * Removes the type from the TypeLibraryDependencyType. No operation * otherwise. Returns true if there was a modification. * * @param typeLibraryDependencyType the type library dependency type * @param typeName the type name * @return true, if successful */ public static boolean removeTypeEntryIfExists( TypeLibraryDependencyType typeLibraryDependencyType, String typeName) { TypeDependencyType typeDepToBeRemoved = getTypeEntry( typeLibraryDependencyType, typeName); if (typeDepToBeRemoved != null) { typeLibraryDependencyType.getType().remove(typeDepToBeRemoved); return true; } return false; } /** * Finds the library entry under the parameter type type dependency type * with the specified library name and pass it back. Returns null if not * found. Note ReferredTypeLibraryType is the type tag under the root tag * the xml. So this API returns the library referred by the * typeDependencyType passed. * * @param typeDependencyType the type dependency type * @param libraryName the library name * @return the referred type library */ public static ReferredTypeLibraryType getReferredTypeLibrary( TypeDependencyType typeDependencyType, String libraryName) { for (ReferredTypeLibraryType refType : typeDependencyType .getReferredTypeLibrary()) { if (StringUtils.equals(libraryName, refType.getName())) { return refType; } } return null; } /** * Finds the type entry under the parameter type * ReferredTypeLibraryType(library) with the specified type name and pass it * back. Returns null if not found. Note ReferredTypeLibraryType is the * library tag under the type tag the xml. So this API returns the type * referred by referredTypeLibraryType among different types. One type might * depend on many types from the same type library. This API returns the * type with the specified name * * @param referredTypeLibraryType the referred type library type * @param typeName the type name * @return the referred type */ public static ReferredType getReferredType( ReferredTypeLibraryType referredTypeLibraryType, String typeName) { for (ReferredType referredType : referredTypeLibraryType .getReferredType()) { if (StringUtils.equals(typeName, referredType.getName())) { return referredType; } } return null; } /** * Name says it all. Unmarshalls the file to a model java object. * Additionally it refresh the file to make sure that it is in sync * * @param file the file * @return the type library dependency type * @throws JAXBException the jAXB exception * @throws CoreException the core exception */ public static TypeLibraryDependencyType unmarshallIt(IFile file) throws JAXBException, CoreException { WorkspaceUtil.refresh(file); InputStream inputStream = file.getContents(); try { return unmarshallIt(inputStream); } finally { IOUtils.closeQuietly(inputStream); } } /** * Name says it all. Unmarshalls the file to a model java object. * Additionally it refresh the file to make sure that it is in sync * * @param inputStream the input stream * @return the type library dependency type * @throws JAXBException the jAXB exception * @throws CoreException the core exception */ public static TypeLibraryDependencyType unmarshallIt(InputStream inputStream) throws JAXBException, CoreException { try { ITypeRegistryBridge birdge = GlobalRepositorySystem.instanceOf() .getActiveRepositorySystem().getTypeRegistryBridge(); return birdge.unmarshalTypeLibraryDependencyType(inputStream); } finally { IOUtils.closeQuietly(inputStream); } } /** * Marshalls the java model object back to a file. Write operation. * Additionally does a refresh * * @param typeLibraryDependencyType the type library dependency type * @param file the file * @throws JAXBException the jAXB exception * @throws CoreException the core exception */ public static void marshallIt( TypeLibraryDependencyType typeLibraryDependencyType, IFile file) throws JAXBException, CoreException { ITypeRegistryBridge birdge = GlobalRepositorySystem.instanceOf() .getActiveRepositorySystem().getTypeRegistryBridge(); birdge.marshalTypeLibraryDependencyType(typeLibraryDependencyType, file.getLocation().toFile()); WorkspaceUtil.refresh(file); } /** * Finds all the types under the specified given TypeDependency Type. All * means the types under all referred type libraries under the type * dependency type. * * @param typeDependencyType the type dependency type * @return the all referredtypes * @throws Exception the exception */ public static Set<QName> getAllReferredtypes( TypeDependencyType typeDependencyType) throws Exception { Set<QName> allReferredTypes = new HashSet<QName>(); SOAGlobalRegistryAdapter registryAdapter = SOAGlobalRegistryAdapter.getInstance(); SOATypeRegistry typeRegistry = registryAdapter.getGlobalRegistry(); for (ReferredTypeLibraryType referredTypeLibraryType : typeDependencyType .getReferredTypeLibrary()) { TypeLibraryType typeLib = typeRegistry.getTypeLibrary(referredTypeLibraryType.getName()); if (typeLib == null) { throw new RuntimeException("Could not find the referred type library '" + referredTypeLibraryType.getName() + "' fromt the types registry. Please do a refresh in the Types Explorer view."); } String nameSpace = typeLib.getLibraryNamespace(); for (ReferredType referredType : referredTypeLibraryType .getReferredType()) { allReferredTypes.add(new QName(nameSpace, referredType .getName())); } } return allReferredTypes; } /** * Finds the library to which this type name belongs to. Basically it scans * the whole type libraries and the types inside it and once it finds a * matching name, it does not return the type but the library that contains * the type * * @param typeDependencyType the type dependency type * @param typeName the type name * @return the referred parent type library */ public static ReferredTypeLibraryType getReferredParentTypeLibrary( TypeDependencyType typeDependencyType, String typeName) { for (ReferredTypeLibraryType referredTypeLibraryType : typeDependencyType .getReferredTypeLibrary()) { for (ReferredType referredType : referredTypeLibraryType .getReferredType()) { if (StringUtils.equalsIgnoreCase(typeName, referredType .getName())) { return referredTypeLibraryType; } } } return null; } /** * Removes all the referred type libraries from this type dependency type. * Initially we thought we name it removeAllReferredTypeLibraries. But * actually even if its removing the libraries, the ultimate effect is that * all the types under it is also removed. So that why we have kept this * name. * * @param typeDependencyType the type dependency type */ public static void removeAllReferredTypes( TypeDependencyType typeDependencyType) { List<ReferredTypeLibraryType> allreferredTypeLibs = new ArrayList<ReferredTypeLibraryType>( typeDependencyType.getReferredTypeLibrary()); typeDependencyType.getReferredTypeLibrary().removeAll( allreferredTypeLibs); } /** * Adds all the new referred types to the TypeDependency Type. This API * takes care of missing referredTypeLibrary also, Meaning this will add * missing referred libraries also. The old refTypes is used for finding out * the version. Basically we don't want to change the version here, we would * like to keep the old version and thats why we need the old referred types * * @param typeDependencyType the type dependency type * @param newRefTypes the new ref types * @param oldRefTypes the old ref types */ public static void addAllReferredTypes( TypeDependencyType typeDependencyType, Set<LibraryType> newRefTypes, Set<ReferredType> oldRefTypes) { for (LibraryType libraryType : newRefTypes) { addReferredTypeLibraryIfNotExists(libraryType, typeDependencyType); ReferredTypeLibraryType referredTypeLibraryType = getReferredTypeLibrary( typeDependencyType, libraryType.getLibraryInfo() .getLibraryName()); addReferredTypeUnderTypeLibrary(libraryType, referredTypeLibraryType, oldRefTypes); } } /** * Gets all referred type libraries in this type dependency xml. Basically * it scans the xml finds all the types and go inside each type and find all * the referred type library and returns it, * * @param typeLibraryDependencyType the type library dependency type * @return the all referred type libraries */ public static Set<String> getAllReferredTypeLibraries( TypeLibraryDependencyType typeLibraryDependencyType) { Set<String> allReferredTypeLibraries = new HashSet<String>(); for (TypeDependencyType type : typeLibraryDependencyType.getType()) { for (ReferredTypeLibraryType referredTypeLibraryType : type .getReferredTypeLibrary()) { allReferredTypeLibraries.add(referredTypeLibraryType.getName()); } } return allReferredTypeLibraries; } /** * Gets all referred types in this type dependency xml. Basically it scans * the xml, finds all the types and go inside each type and find all the * referred type library and goes inside each type library and finds all * referred types and returns it, * * @param typeLibraryDependencyType the type library dependency type * @return the all referred types * @throws Exception the exception */ public static Set<QName> getAllReferredTypes( TypeLibraryDependencyType typeLibraryDependencyType) throws Exception { Set<QName> allReferredTypes = new HashSet<QName>(); SOAGlobalRegistryAdapter registryAdapter = SOAGlobalRegistryAdapter.getInstance(); SOATypeRegistry typeRegistry = registryAdapter.getGlobalRegistry(); for (TypeDependencyType type : typeLibraryDependencyType.getType()) { for (ReferredTypeLibraryType referredTypeLibraryType : type .getReferredTypeLibrary()) { for (ReferredType referredType : referredTypeLibraryType .getReferredType()) { allReferredTypes.add(new QName(typeRegistry.getTypeLibrary( referredTypeLibraryType.getName()) .getLibraryNamespace(), referredType.getName())); } } } return allReferredTypes; } /** * Gets all referred types in this type dependency xml. Basically it scans * the xml, finds all the types and go inside each type and find all the * referred type library and goes inside each type library and finds all * referred types and returns it, * * @param typeLibraryDependencyType the type library dependency type * @return the aLL referred types */ public static Set<ReferredType> getALLReferredTypes( TypeLibraryDependencyType typeLibraryDependencyType) { Set<ReferredType> allReferredTypes = new HashSet<ReferredType>(); for (TypeDependencyType type : typeLibraryDependencyType.getType()) { for (ReferredTypeLibraryType referredTypeLibraryType : type .getReferredTypeLibrary()) { for (ReferredType referredType : referredTypeLibraryType .getReferredType()) { allReferredTypes.add(referredType); } } } return allReferredTypes; } private static void addTypeEntry(LibraryType libraryType, TypeLibraryDependencyType typeLibraryDependencyType) { TypeDependencyType typeDependencyType = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem() .getTypeRegistryBridge().createTypeDependencyTypeInstance(); typeDependencyType.setName(libraryType.getName()); typeDependencyType.setVersion(libraryType.getVersion()); typeLibraryDependencyType.getType().add(typeDependencyType); } private static void addReferredTypeLibrary(LibraryType addedType, TypeDependencyType typeDependencyType) { ReferredTypeLibraryType referredTypeLibraryType = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem() .getTypeRegistryBridge().createReferredTypeLibraryTypeInstance(); referredTypeLibraryType.setName(addedType.getLibraryInfo() .getLibraryName()); referredTypeLibraryType.setVersion(addedType.getLibraryInfo() .getVersion()); typeDependencyType.getReferredTypeLibrary() .add(referredTypeLibraryType); } private static boolean addReferredTypeLibraryIfNotExists( LibraryType addedType, TypeDependencyType typeDependencyType) { if (getReferredTypeLibrary(typeDependencyType, addedType .getLibraryInfo().getLibraryName()) == null) { addReferredTypeLibrary(addedType, typeDependencyType); return true; } return false; } private static void addReferredTypeUnderTypeLibrary(LibraryType addedType, ReferredTypeLibraryType referredTypeLibraryType, Set<ReferredType> oldReferredTypes) { ReferredType refType = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem() .getTypeRegistryBridge().createReferredTypeInstance(); refType.setName(addedType.getName()); String version = addedType.getVersion(); for (ReferredType referredType : oldReferredTypes) { if (StringUtils.equals(addedType.getName(), referredType.getName())) { version = referredType.getVersion(); break; } } refType.setVersion(version); referredTypeLibraryType.getReferredType().add(refType); } }