package org.objectstyle.wolips.bindings.api; import java.io.File; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IOpenable; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.SearchPattern; import org.objectstyle.wolips.bindings.Activator; import org.objectstyle.wolips.bindings.utils.BindingReflectionUtils; import org.objectstyle.wolips.bindings.wod.BindingValueKey; import org.objectstyle.wolips.bindings.wod.TypeCache; import org.objectstyle.wolips.core.resources.types.TypeNameCollector; import org.objectstyle.wolips.core.resources.types.project.ProjectAdapter; import org.objectstyle.wolips.jdt.ProjectFrameworkAdapter; import org.objectstyle.wolips.locate.LocatePlugin; import org.objectstyle.wolips.locate.result.LocalizedComponentsLocateResult; import org.osgi.framework.Bundle; public class ApiUtils { private static ApiModel _globalApiModel; public static boolean isActionBinding(IApiBinding binding) { String defaults = binding.getDefaults(); boolean isActionBinding = false; if (IApiBinding.ACTIONS_DEFAULT.equals(defaults)) { isActionBinding = true; } else if (defaults == null) { String bindingName = binding.getName(); isActionBinding = "action".equals(bindingName) || bindingName.endsWith("Action"); } return isActionBinding; } public static int getSelectedDefaults(IApiBinding binding) { String defaults = binding.getDefaults(); if (defaults == null) { return 0; } for (int i = 0; i < IApiBinding.ALL_DEFAULTS.length; i++) { String string = IApiBinding.ALL_DEFAULTS[i]; if (string.equals(defaults)) { return i; } } return 0; } public static Wo findApiModelWo(IType elementType, ApiCache cache) throws ApiModelException { Wo wo; if (elementType == null) { wo = null; } else { wo = cache.getApiForType(elementType); if (wo != null) { ApiModel model = wo.getModel(); if (model.parseIfNecessary()) { cache.clearApiForElementType(elementType); wo = null; } } if (wo == null) { Boolean apiMissing = cache.apiMissingForElementType(elementType); if (apiMissing == null || !apiMissing.booleanValue()) { ApiModel apiModel = null; try { if (elementType.getFullyQualifiedName().startsWith("com.webobjects.appserver._private.")) { if (_globalApiModel == null) { Bundle bundle = Activator.getDefault().getBundle(); URL woDefinitionsURL = bundle.getEntry("/WebObjectDefinitions.xml"); if (woDefinitionsURL != null) { apiModel = new ApiModel(woDefinitionsURL); } _globalApiModel = apiModel; } else { apiModel = _globalApiModel; } } else { IOpenable typeContainer = elementType.getOpenable(); if (typeContainer instanceof IClassFile) { IClassFile classFile = (IClassFile) typeContainer; IJavaElement parent = classFile.getParent(); if (parent instanceof IPackageFragment) { IPackageFragment parentPackage = (IPackageFragment) parent; IJavaElement parentParent = parentPackage.getParent(); // [apl 25.june.2008] // We check to see if in fact the resource is contained // within a jar file. This is the case if the framework // has been bundled into "jar style" framework. if(parentParent instanceof IPackageFragmentRoot && "jar".equalsIgnoreCase(parentParent.getPath().getFileExtension())) { String jarResourcePath = "Resources/" + elementType.getElementName() + ".api"; String jarOSPath = parentParent.getPath().toOSString(); File jarOSFile = new File(jarOSPath); if(jarOSFile.exists()) { JarFile jarFile = new JarFile(jarOSFile); JarEntry je = jarFile.getJarEntry(jarResourcePath); if (je != null && je.getSize() != 0) { apiModel = new ApiModel(new URL("jar:file:"+jarOSPath+"!/"+jarResourcePath)); } } } if (apiModel == null) { IPath packagePath = parentPackage.getPath(); IPath apiPath = packagePath.removeLastSegments(2).append(elementType.getElementName()).addFileExtension("api"); File apiFile = apiPath.toFile(); boolean fileExists = apiFile.exists(); if (fileExists) { apiModel = new ApiModel(apiFile); } } // [apl] - end change. } } else if (typeContainer instanceof ICompilationUnit) { // ICompilationUnit cu = (ICompilationUnit) // typeContainer; // IResource resource = cu.getCorrespondingResource(); // String name = resource.getName(); LocalizedComponentsLocateResult componentsLocateResults = LocatePlugin.getDefault().getLocalizedComponentsLocateResult(elementType.getJavaProject().getProject(), elementType.getElementName()); IFile apiFile = componentsLocateResults.getDotApi(); if (apiFile != null && apiFile.exists()) { apiModel = new ApiModel(apiFile); } } } if (apiModel != null) { Wo[] wos = apiModel.getWODefinitions().getWos(); if (wos.length == 0) { // leave it alone } else if (wos.length == 1) { wo = wos[0]; } else { for (int i = 0; wo == null && i < wos.length; i++) { if (elementType.getElementName().equals(wos[i].getClassName())) { wo = wos[i]; } } } } } catch (Throwable t) { wo = null; Activator.getDefault().log("Failed to parse API for " + elementType.getElementName() + ".", t); } if (wo == null) { cache.setApiMissingForElementType(true, elementType); } else { cache.setApiForType(wo, elementType); } } } } return wo; } public static String[] getValidValues(String partialValue, IJavaProject javaProject, IType componentType, IType apiType, String bindingName, TypeCache typeCache) throws JavaModelException, ApiModelException { String[] validValues = null; Wo wo = ApiUtils.findApiModelWo(apiType, typeCache.getApiCache(javaProject)); if (wo != null) { Binding matchingBinding = wo.getBinding(bindingName); if (matchingBinding != null) { validValues = matchingBinding.getValidValues(partialValue, javaProject, componentType, typeCache); } } return validValues; } public static String[] getValidValues(IApiBinding binding, String partialValue, IJavaProject javaProject, IType componentType, TypeCache typeCache) throws JavaModelException { Set<String> validValues = new HashSet<String>(); int selectedDefaults = binding.getSelectedDefaults(); String defaultsName = IApiBinding.ALL_DEFAULTS[selectedDefaults]; if ("Boolean".equals(defaultsName)) { validValues.add("true"); validValues.add("false"); } else if ("YES/NO".equals(defaultsName)) { validValues.add("yes"); validValues.add("no"); } else if ("Date Format Strings".equals(defaultsName)) { validValues.add("\"%m/%d/%y\""); validValues.add("\"%B %d, %Y\""); validValues.add("\"%b %d, %Y\""); validValues.add("\"%A, %B %d, %Y\""); validValues.add("\"%A, %b %d, %Y\""); validValues.add("\"%d.%m.%y\""); validValues.add("\"%d %B %y\""); validValues.add("\"%d %b %y\""); validValues.add("\"%A %d %B %Y\""); validValues.add("\"%A %d %b %Y\""); validValues.add("\"%x\""); validValues.add("\"%H:%M:%S\""); validValues.add("\"%I:%M:%S %p\""); validValues.add("\"%H:%M\""); validValues.add("\"%I:%M %p\""); validValues.add("\"%X\""); } else if ("Number Format Strings".equals(defaultsName)) { validValues.add("\"0\""); validValues.add("\"0.00\""); validValues.add("\"0.##\""); validValues.add("\"#,##0\""); validValues.add("\"_,__0\""); validValues.add("\"#,##0.00\""); validValues.add("\"$#,##0\""); validValues.add("\"$#,##0.00\""); validValues.add("\"$#,##0.##\""); } else if ("MIME Types".equals(defaultsName)) { validValues.add("\"image/gif\""); validValues.add("\"image/jpeg\""); validValues.add("\"image/png\""); } else if ("Direct Actions".equals(defaultsName)) { if (partialValue != null && partialValue.startsWith("\"")) { TypeNameCollector typeNameCollector = new TypeNameCollector("com.webobjects.appserver.WODirectAction", javaProject, false); BindingReflectionUtils.findMatchingElementClassNames("", SearchPattern.R_PREFIX_MATCH, typeNameCollector, new NullProgressMonitor()); for (IType type : typeNameCollector.types()) { IMethod[] methods = type.getMethods(); for (IMethod method : methods) { String name = method.getElementName(); if (name.endsWith("Action") && method.getParameterNames().length == 0) { validValues.add("\"" + name.substring(0, name.length() - "Action".length()) + "\""); } } } } } else if ("Direct Action Classes".equals(defaultsName)) { if (partialValue != null && partialValue.startsWith("\"")) { TypeNameCollector typeNameCollector = new TypeNameCollector("com.webobjects.appserver.WODirectAction", javaProject, false); BindingReflectionUtils.findMatchingElementClassNames(partialValue.substring(1), SearchPattern.R_PREFIX_MATCH, typeNameCollector, new NullProgressMonitor()); for (String typeName : typeNameCollector.getTypeNames()) { int dotIndex = typeName.lastIndexOf('.'); if (dotIndex != -1) { typeName = typeName.substring(dotIndex + 1); } validValues.add("\"" + typeName + "\""); } } } else if ("Page Names".equals(defaultsName)) { if (partialValue != null && partialValue.startsWith("\"")) { TypeNameCollector typeNameCollector = new TypeNameCollector(javaProject, false); BindingReflectionUtils.findMatchingElementClassNames(partialValue.substring(1), SearchPattern.R_PREFIX_MATCH, typeNameCollector, new NullProgressMonitor()); for (String typeName : typeNameCollector.getTypeNames()) { int dotIndex = typeName.lastIndexOf('.'); if (dotIndex != -1) { typeName = typeName.substring(dotIndex + 1); } validValues.add("\"" + typeName + "\""); } } } else if ("Frameworks".equals(defaultsName)) { if (partialValue != null && partialValue.startsWith("\"")) { validValues.add("\"app\""); ProjectFrameworkAdapter projectFrameworkAdapter = (ProjectFrameworkAdapter) javaProject.getProject().getAdapter(ProjectFrameworkAdapter.class); if (projectFrameworkAdapter != null) { for (String frameworkName : projectFrameworkAdapter.getLinkedFrameworkNames()) { validValues.add("\"" + frameworkName + "\""); } } } } else if ("Resources".equals(defaultsName)) { ProjectAdapter projectAdapter = (ProjectAdapter) javaProject.getProject().getAdapter(ProjectAdapter.class); if (projectAdapter != null) { IFolder folder = projectAdapter.getBuildAdapter().getProductAdapter().getContentsAdapter().getWebServerResourcesAdapter().getUnderlyingFolder(); try { ApiUtils.acceptResources(folder, "", validValues); } catch (CoreException e) { e.printStackTrace(); } } } else if ("Actions".equals(defaultsName)) { List<BindingValueKey> bindingKeysList = BindingReflectionUtils.getBindingKeys(javaProject, componentType, "", false, BindingReflectionUtils.VOID_ONLY, false, typeCache); for (BindingValueKey key : bindingKeysList) { validValues.add(key.getBindingName()); } } String[] validValueStrings = validValues.toArray(new String[validValues.size()]); return validValueStrings; } protected static void acceptResources(IResource resource, String basePath, Set<String> paths) throws CoreException { if (resource instanceof IFolder) { IResource[] members = ((IFolder) resource).members(); for (IResource childResource : members) { if (childResource instanceof IFolder) { ApiUtils.acceptResources(childResource, basePath + "/" + childResource.getName() + "/", paths); } else { ApiUtils.acceptResources(childResource, basePath, paths); } } } else if (resource instanceof IFile) { paths.add("\"" + basePath + resource.getName() + "\""); } } }