/******************************************************************************* * 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.builders; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.ebayopensource.turmeric.eclipse.codegen.utils.CodegenInvoker; import org.ebayopensource.turmeric.eclipse.core.TurmericCoreActivator; import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger; 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.RepositorySystemActivator; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem; import org.ebayopensource.turmeric.eclipse.resources.util.SOAServiceUtil; import org.ebayopensource.turmeric.eclipse.typelibrary.utils.TypeLibraryUtil; import org.ebayopensource.turmeric.eclipse.utils.classloader.SOAPluginClassLoader; import org.ebayopensource.turmeric.eclipse.utils.plugin.EclipseMessageUtils; import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.JavaCore; /** * * Standard Type Library Builder Utils. * * @author smathew * */ public class TypeLibraryBuilderUtils { private static final SOALogger logger = SOALogger.getLogger(); /** * Wrapper API for TypeLibraryDeltaVisitor pattern. Returns all the XSDs * which has been modified according to the delta * * @param delta - * resource delta * @param project the project * @return list of modified xsds. * @throws CoreException the core exception */ public static List<IFile> getModifiedXsds(IResourceDelta delta, IProject project) throws CoreException { TypeLibraryDeltaVisitor typeLibraryDeltaVisitor = new TypeLibraryDeltaVisitor( project); delta.accept(typeLibraryDeltaVisitor); return typeLibraryDeltaVisitor.getModifiedXsds(); } /** * Examine if the project is not null, accessible, has type lib nature. It * also examines the readability and writability aspect. * * @param project - * the project to be examined. * @return the i status * @throws Exception the exception */ public static IStatus checkProjectHealth(final IProject project) throws Exception { if (project == null) return EclipseMessageUtils.createErrorStatus( RepositorySystemActivator.PLUGIN_ID, "Project is null", null); if (project.isAccessible() == false) return EclipseMessageUtils.createResourceErrorStatus(project .getLocation(), "Project is not accessible->" + project, null); if (!project.hasNature(TypeLibraryProjectNature.getTypeLibraryNatureId())) { return EclipseMessageUtils.createResourceErrorStatus(project .getLocation(), "Project is not a valid Type library project->" + project, null); } for (final IResource resource : TurmericCoreActivator.getTypeLibProjectReadableResources(project)) { if (WorkspaceUtil.isResourceReadable(resource) == false) { return EclipseMessageUtils.createResourceWarnStatus(resource .getLocation(), "Resource does not exist or is not readable->" + resource.getName(), null); } } for (final IResource resource : TurmericCoreActivator.getTypeLibProjectWritableResources(project)) { if (WorkspaceUtil.isResourceModifiable(resource) == false) { return EclipseMessageUtils.createSOAResourceWarnStatus( resource, "Resource does not exist or is not modifiable->" + resource.getName(), null); } } return Status.OK_STATUS; } /** * Validate the xsd for any wtp validation issues. * * @param project - * the parent project * @param complainAboutMissingXSDs - * if this is true if there is a missing xsd file( opposed to the * type info x), * @return the multi status * @throws Exception the exception */ public static MultiStatus validateXSDS(IProject project, boolean complainAboutMissingXSDs) throws Exception { SOAXSDValidator sOAXSdValidator = new SOAXSDValidator(); ArrayList<IStatus> statusList = new ArrayList<IStatus>(); MultiStatus multiStatus = (MultiStatus) EclipseMessageUtils .createEmptyOKMultiStatus("XSD Validation"); for (IFile file : TypeLibraryUtil.getAllXsdFiles(project, true)) { if (file != null && file.isAccessible()) { statusList.add(sOAXSdValidator.validate(file)); } else { if (complainAboutMissingXSDs) statusList .add(EclipseMessageUtils .createResourceErrorStatus( project.getFullPath(), "This XSD type has an entry in typeinformation.xml and is not accessible now. Please fix this.->" + file.getName(), null)); } } if (!statusList.isEmpty()) { multiStatus = (MultiStatus) EclipseMessageUtils .createErrorMultiStatus(statusList, "XSD Validation"); } return multiStatus; } /** * Checks an interface project's health against soa standards. We might have * to move it to interface package. but a small problem is that this checks * mainly for the type library dependency feature prerequisites. WSDL should * be there, Type Dependency file should be there. Nature should be correct. * * @param project the project * @return the i status * @throws Exception the exception */ public static IStatus checkProjectHealthForIntfProject( final IProject project) throws Exception { if (project == null) return EclipseMessageUtils.createErrorStatus( RepositorySystemActivator.PLUGIN_ID, "Project is null", null); if (project.isAccessible() == false) return EclipseMessageUtils.createResourceErrorStatus(project .getLocation(), "Project is not accessible->" + project, null); if (project .hasNature(GlobalRepositorySystem.instanceOf().getActiveRepositorySystem() .getProjectNatureId(SupportedProjectType.INTERFACE)) == false) { return EclipseMessageUtils.createResourceErrorStatus(project .getLocation(), "Project is not a valid Interface project->" + project, null); } for (final IResource resource : getIntfProjectReadableResources(project)) { if (WorkspaceUtil.isResourceReadable(resource) == false) { return EclipseMessageUtils.createResourceWarnStatus(resource .getLocation(), "Resource does not exist or is not readable->" + resource.getName(), null); } } for (final IResource resource : getIntfProjectWritableResources(project)) { if (WorkspaceUtil.isResourceModifiable(resource) == false) { return EclipseMessageUtils.createResourceWarnStatus(resource .getLocation(), "Resource does not exist or is not modifiable->" + resource.getName(), null); } } return Status.OK_STATUS; } private static List<IResource> getIntfProjectWritableResources( IProject project) { final List<IResource> resources = new ArrayList<IResource>(); TurmericCoreActivator.getDependencyFile(project); return resources; } private static List<IResource> getIntfProjectReadableResources( IProject project) { final List<IResource> resources = new ArrayList<IResource>(); resources.add(SOAServiceUtil.getWsdlFile(project.getName())); return resources; } /** * Mainly used to validate a type library project. These are the minimum * files that should be readable for the SOA plugin and codegen to work. For * now its just the type dependency file. * * @param project * @return list of resources that are supposed to exist in a valid type * library project. * @throws Exception */ public static List<IResource> getTypeLibProjectReadableResources( final IProject project) throws Exception { final List<IResource> resources = new ArrayList<IResource>(); resources.add(TypeLibraryUtil.getDependencyFile(project)); return resources; } /** * Mainly used to validate a type library project. These are the minimum * files that should be writable for the SOA plugin and codegen to modify. * The returned list of files could be modified either by codegen or soa * plugin. For now its just the type dependency file. * * @param project * @return list of resources that are supposed tobe writable in a valid type * library project. * @throws Exception */ public static List<IResource> getTypeLibProjectWritableResources( final IProject project) throws Exception { final List<IResource> resources = new ArrayList<IResource>(); resources.add(TypeLibraryUtil.getDependencyFile(project)); return resources; } /** * Creates a Codegen Invoker and populates its class loader with type * libraries. In addition there is a cryptic process that this function * performs. 1) Find out the output location typically project\bin. 2) * Removes it from the classpath. 3) Add meta src and meta inf folders to * the class path. This is to make sure that the latest XSDs and xml * modified by the user are present in the class path and not the stale old * output xsds and xmls. * * @param project the project * @return the codegen invoker * @throws Exception the exception */ public static CodegenInvoker initForTypeLib(IProject project) throws Exception { CodegenInvoker codegenInvoker = CodegenInvoker.init(project); SOAPluginClassLoader soaPluginClassLoader = codegenInvoker .getSoaPluginClassLoader(); ArrayList<IProject> typeLibProjects = WorkspaceUtil .getProjectsByNature(TypeLibraryProjectNature.getTypeLibraryNatureId()); soaPluginClassLoader.setPluginBundles( (GlobalRepositorySystem .instanceOf().getActiveRepositorySystem() .getTypeRegistryBridge().getPluginBundles())); // Output location of each project ArrayList<URL> outPutUrls = new ArrayList<URL>(); ArrayList<URL> metasrcmetainfUrls = new ArrayList<URL>(); for (IProject typeLibProject : typeLibProjects) { outPutUrls.add(typeLibProject.getFolder( JavaCore.create(typeLibProject).getOutputLocation() .removeFirstSegments(1)).getLocation().toFile() .toURI().toURL()); // we always love to have recent xsds and recent xmls :). metasrcmetainfUrls.add(typeLibProject.getFolder( SOATypeLibraryConstants.FOLDER_GEN_META_SRC).getLocation() .toFile().toURI().toURL()); metasrcmetainfUrls.add(typeLibProject.getFolder( SOATypeLibraryConstants.FOLDER_META_SRC).getLocation() .toFile().toURI().toURL()); } Set<URL> classPathList = soaPluginClassLoader.getM_classPathURLs(); Iterator<URL> iterator = classPathList.iterator(); while (iterator.hasNext()) { URL nextUrl = iterator.next(); for (URL url : outPutUrls) { if (StringUtils.equalsIgnoreCase(nextUrl.toString(), url .toString())) { // we dont want the ouput location. It contains stale xmls // and xsds. // bad bad remove them iterator.remove(); break; } } } classPathList.addAll(metasrcmetainfUrls); soaPluginClassLoader.setM_classPathURLs(classPathList); if (SOALogger.DEBUG) { logger.debug("Init for Type Lib, Final Urls are: " + soaPluginClassLoader.getM_classPathURLs()); } return codegenInvoker; } }