Java tutorial
/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.seam.core; import java.io.File; import java.io.IOException; import java.util.Set; import java.util.StringTokenizer; import java.util.jar.Attributes; import java.util.jar.JarFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.jst.j2ee.project.EarUtilities; import org.eclipse.jst.j2ee.project.WebUtilities; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualReference; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.text.ITextSourceReference; import org.jboss.tools.jst.web.WebModelPlugin; import org.jboss.tools.jst.web.kb.IKbProject; import org.jboss.tools.jst.web.kb.internal.KbBuilder; import org.jboss.tools.seam.core.project.facet.SeamRuntime; import org.jboss.tools.seam.internal.core.AbstractContextVariable; import org.jboss.tools.seam.internal.core.SeamComponentDeclaration; /** * @author Alexey Kazakov */ public class SeamUtil { public static void enableSeamSupport(IProject project) { if (project == null) { return; } try { WebModelPlugin.addNatureToProjectWithValidationSupport(project, KbBuilder.BUILDER_ID, IKbProject.NATURE_ID); WebModelPlugin.addNatureToProjectWithValidationSupport(project, SeamCoreBuilder.BUILDER_ID, ISeamProject.NATURE_ID); } catch (CoreException e) { SeamCorePlugin.getPluginLog().logError(e); } } /** * Returns Seam version from <Seam Runtime>/lib/jboss-seam.jar/META-INF/MANIFEST.MF * from Seam Runtime which is set for the project. * @param project * @return */ public static String getSeamVersionFromManifest(IProject project) { ISeamProject seamProject = SeamCorePlugin.getSeamProject(project, false); if (seamProject == null) { SeamCorePlugin.getPluginLog().logWarning("Can't find Seam Project for " + project.getName()); return null; } return getSeamVersionFromManifest(seamProject); } /** * Returns Seam version from <Seam Runtime>/lib/jboss-seam.jar/META-INF/MANIFEST.MF * from Seam Runtime which is set for the project. * @param project * @return */ public static String getSeamVersionFromManifest(ISeamProject project) { SeamRuntime runtime = project.getRuntime(); if (runtime == null) { SeamCorePlugin.getPluginLog() .logWarning("Seam Runtime for " + project.getProject().getName() + " is null."); return null; } return getSeamVersionFromManifest(runtime); } private final static String SEAM_JAR_NAME = "jboss-seam.jar"; private final static String SEAM_VERSION_ATTRIBUTE_NAME = "Seam-Version"; private final static String IMPLEMENTATION_VERSION_ATTRIBUTE_NAME = "Implementation-Version"; /** * Returns Seam version from <Seam Runtime>/lib/jboss-seam.jar/META-INF/MANIFEST.MF * from Seam Runtime. * @param runtime * @return */ public static String getSeamVersionFromManifest(SeamRuntime runtime) { return getSeamVersionFromManifest(runtime.getHomeDir()); } /** * Returns trimmed Seam version from <SeamHome>/lib/jboss-seam.jar/META-INF/MANIFEST.MF * @param depth - number of segments of Seam version string. * @param seamHome * @return */ public static String getSeamVersionFromManifest(String seamHome, int depth) { return trimSeamVersion(getSeamVersionFromManifest(seamHome), depth); } /** * Returns true if two versions are matched. * For example "2.1.1.GA" matches "2.1" * @param version1 * @param version2 * @return */ public static boolean areSeamVersionsMatched(String version1, String version2) { String longerVersion = version1.length() > version2.length() ? version1 : version2; String shorterVersion = longerVersion == version1 ? version2 : version1; StringTokenizer sSt = new StringTokenizer(shorterVersion, ".", false); StringTokenizer lSt = new StringTokenizer(longerVersion, ".", false); while (sSt.hasMoreElements() && lSt.hasMoreElements()) { if (!sSt.nextToken().equals(lSt.nextToken())) { return false; } } return true; } /** * Returns Seam version from <SeamHome>/lib/jboss-seam.jar/META-INF/MANIFEST.MF * @param seamHome * @return */ public static String getSeamVersionFromManifest(String seamHome) { File jarFile = new File(seamHome, "lib/" + SEAM_JAR_NAME); if (!jarFile.isFile()) { jarFile = new File(seamHome, SEAM_JAR_NAME); if (!jarFile.isFile()) { // Don't log this. See https://jira.jboss.org/browse/JBIDE-7038 // SeamCorePlugin.getPluginLog().logWarning(jarFile.getAbsolutePath() + " as well as " + new File(seamHome, "lib/" + seamJarName).getAbsolutePath() + " don't exist."); return null; } } try { JarFile jar = new JarFile(jarFile); Attributes attributes = jar.getManifest().getMainAttributes(); String version = attributes.getValue(SEAM_VERSION_ATTRIBUTE_NAME); if (version == null) { SeamCorePlugin.getPluginLog() .logWarning("Can't get Seam-Version from " + jar.getName() + " MANIFEST."); version = attributes.getValue(IMPLEMENTATION_VERSION_ATTRIBUTE_NAME); if (version == null) { SeamCorePlugin.getPluginLog() .logWarning("Can't get Implementation-Version from " + jar.getName() + " MANIFEST."); } } return version; } catch (IOException e) { SeamCorePlugin.getPluginLog().logError(e); return null; } } /** * Trims Seam version string. * For example "2.1.0.SP1" will be trimmed to 2.1 (depth=2); "2.1.1.GA" -> "2.1.1" (depth=3); "2.0.0.SP1" -> "2.0.0.SP1" (depth<1) * @param fullSeamVersion * @param depth - number of segments of Seam version string. * @return */ public static String trimSeamVersion(String fullSeamVersion, int depth) { if (fullSeamVersion == null || depth < 1) { return fullSeamVersion; } StringBuffer version = new StringBuffer(); StringTokenizer st = new StringTokenizer(fullSeamVersion, ".", false); while (st.hasMoreElements() && depth > 0) { version.append(st.nextToken()); depth--; if (st.hasMoreElements() && depth > 0) { version.append('.'); } } return version.toString(); } /** * Converts seam project name to string which suitable for package names * @param projectNamePackage * @return */ public static String getSeamPackageName(String projectName) { if (projectName == null) return null; String packageName = projectName.toLowerCase(); if (packageName.indexOf(" ") >= 0) packageName = packageName.replace(" ", ""); if (packageName.indexOf("-") >= 0) packageName = packageName.replace("-", ""); if (packageName.indexOf("+") >= 0) packageName = packageName.replace("+", ""); if (packageName.indexOf("_") >= 0) packageName = packageName.replace("_", ""); while (packageName.indexOf("..") >= 0) { packageName = packageName.replace("..", "."); } return packageName; } /** * Finds referencing Seam war project * @param project * @return */ public static ISeamProject findReferencingSeamWarProjectForProject(IProject project) { return findReferencingSeamWarProjectForProject(project, true); } /** * Finds referencing Seam war project * @param project * @param searchInEARs if "true" then try to search web projects in parent EAR project. * @return */ public static ISeamProject findReferencingSeamWarProjectForProject(IProject project, boolean searchInEARs) { IProject[] referencing = J2EEProjectUtilities.getReferencingWebProjects(project); for (int i = 0; i < referencing.length; i++) { ISeamProject seamProject = SeamCorePlugin.getSeamProject(referencing[i], false); if (seamProject != null) { return seamProject; } } if (searchInEARs) { referencing = EarUtilities.getReferencingEARProjects(project); for (int i = 0; i < referencing.length; i++) { ISeamProject seamProject = findReferencingSeamWarProjectForProject(referencing[i], false); if (seamProject != null) { return seamProject; } } IVirtualComponent comp = ComponentCore.createComponent(project); IVirtualReference[] refComponents = null; if (comp != null) { refComponents = comp.getReferences(); for (IVirtualReference virtualReference : refComponents) { IVirtualComponent component = virtualReference.getReferencedComponent(); if (component != null && !component.isBinary() && WebUtilities.isDynamicWebComponent(component)) { ISeamProject seamProject = SeamCorePlugin.getSeamProject(component.getProject(), false); if (seamProject != null) { return seamProject; } } } } } return null; } /** * @param element * @return Resource of seam model element */ public static IResource getComponentResourceWithName(ISeamElement element) { if (element instanceof ISeamComponent) { Set<ISeamComponentDeclaration> declarations = ((ISeamComponent) element).getAllDeclarations(); for (Object o : declarations) { SeamComponentDeclaration d = (SeamComponentDeclaration) o; ITextSourceReference location = d.getLocationFor(SeamComponentDeclaration.PATH_OF_NAME); if (!isEmptyLocation(location)) { return d.getResource(); } } } return element.getResource(); } /** * @param seam model element * @return location of name attribute */ public static ITextSourceReference getLocationOfName(ISeamElement element) { return getLocationOfAttribute(element, SeamComponentDeclaration.PATH_OF_NAME); } /** * @param seam model element * @return location of attribute */ public static ITextSourceReference getLocationOfAttribute(ISeamElement element, String attributeName) { ITextSourceReference location = null; if (element instanceof AbstractContextVariable) { location = ((AbstractContextVariable) element).getLocationFor(attributeName); } else if (element instanceof ISeamComponent) { Set<ISeamComponentDeclaration> declarations = ((ISeamComponent) element).getAllDeclarations(); for (ISeamComponentDeclaration d : declarations) { location = ((SeamComponentDeclaration) d).getLocationFor(attributeName); if (!isEmptyLocation(location)) { break; } } } else if (element instanceof SeamComponentDeclaration) { location = ((SeamComponentDeclaration) element).getLocationFor(attributeName); } if (isEmptyLocation(location) && element instanceof ITextSourceReference) { location = (ITextSourceReference) element; } return location; } public static boolean isEmptyLocation(ITextSourceReference location) { return (location == null //is dead location, we cannot now change provider to return null //because it may give rise to other errors. //In the future, null should be returned instead of 'dead' location //and correctly processed || location.getStartPosition() == 0 && location.getLength() == 0); } /** * @param resource * @return true if resource is Jar file */ public static boolean isJar(IPath path) { if (path == null) { throw new IllegalArgumentException(SeamCoreMessages.SEAM_VALIDATION_HELPER_RESOURCE_MUST_NOT_BE_NULL); } String ext = path.getFileExtension(); return ext != null && ext.equalsIgnoreCase("jar"); //$NON-NLS-1$ } /** * @param element * @return true if seam element packed in Jar file */ public static boolean isJar(ISeamElement element) { return isJar(element.getSourcePath()); } /** * @param componentXmlFile * @return IType of component for <ComponentName>.component.xml */ public static IType getClassTypeForComponentXml(IFile componentXmlFile, IProject rootProject) { String className = getClassNameForComponentXml(componentXmlFile, rootProject); if (className == null) { return null; } return findType(className, rootProject); } /** * @param type name * @return IType */ public static IType findType(String fullyQualifiedName, IProject rootProject) { try { IJavaProject jp = EclipseResourceUtil.getJavaProject(rootProject); return jp.findType(fullyQualifiedName); } catch (JavaModelException e) { SeamCorePlugin.getDefault().logError(e); return null; } } /** * @param componentXmlFile * @return name of component class for <ComponentName>.component.xml */ public static String getClassNameForComponentXml(IFile componentXmlFile, IProject rootProject) { String fileName = componentXmlFile.getName(); int firstDot = fileName.indexOf('.'); if (firstDot == -1) { return null; } String className = fileName.substring(0, firstDot); try { IJavaProject jp = EclipseResourceUtil.getJavaProject(rootProject); IPackageFragment packageFragment = jp .findPackageFragment(componentXmlFile.getFullPath().removeLastSegments(1)); if (packageFragment == null) { return null; } return packageFragment.getElementName() + "." + className; //$NON-NLS-1$ } catch (JavaModelException e) { SeamCorePlugin.getDefault().logError(e); return null; } } /** * Find a setter or a field for a property. * @param type * @param propertyName * @return IMethod (setter) or IFiled (field) */ public static IMember findProperty(IType type, String propertyName) { if (propertyName == null || propertyName.length() == 0) { return null; } try { return findPropertyInHierarchy(type, propertyName); } catch (JavaModelException e) { SeamCorePlugin.getDefault().logError(e); } return null; } public static IMember findPropertyInHierarchy(IType type, String propertyName) throws JavaModelException { String firstLetter = propertyName.substring(0, 1).toUpperCase(); String nameWithoutFirstLetter = propertyName.substring(1); String setterName = "set" + firstLetter + nameWithoutFirstLetter; //$NON-NLS-1$ IMethod[] methods = type.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getElementName().equals(setterName) && methods[i].getParameterNames().length == 1) { return methods[i]; } } IField[] fields = type.getFields(); for (int i = 0; i < fields.length; i++) { if (fields[i].getElementName().equals(propertyName)) { return fields[i]; } } String superclassName = type.getSuperclassName(); if (superclassName != null) { String[][] packages = type.resolveType(superclassName); if (packages != null) { for (int i = 0; i < packages.length; i++) { String packageName = packages[i][0]; if (packageName != null && packageName.length() > 0) { packageName = packageName + "."; //$NON-NLS-1$ } else { packageName = ""; //$NON-NLS-1$ } String qName = packageName + packages[i][1]; IType superclass = type.getJavaProject().findType(qName); if (superclass != null) { IMember property = findPropertyInHierarchy(superclass, propertyName); if (property != null) { return property; } } } } } return null; } }