blob: 4d62c9698b021e449931d6bf8343931ba7b11cfe [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.j2ee.ejbcore;
import java.util.ArrayList;
import org.netbeans.api.j2ee.core.Profile;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.ClasspathInfo;
import org.netbeans.api.java.source.ElementHandle;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.SourceUtils;
import org.netbeans.api.java.source.Task;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.j2ee.api.ejbjar.EjbJar;
import org.netbeans.modules.j2ee.api.ejbjar.EjbReference;
import org.netbeans.modules.j2ee.core.api.support.java.method.MethodModel;
import org.netbeans.modules.j2ee.core.api.support.java.method.MethodModelSupport;
import org.netbeans.modules.j2ee.dd.api.ejb.Session;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule;
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule.Type;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import org.netbeans.api.java.classpath.JavaClassPathConstants;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.WorkingCopy;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.libraries.Library;
import org.netbeans.modules.j2ee.common.J2eeProjectCapabilities;
import org.netbeans.modules.j2ee.dd.api.ejb.EjbJarMetadata;
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeApplicationProvider;
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
import org.netbeans.modules.j2ee.ejbcore.api.methodcontroller.EjbMethodController;
import org.netbeans.modules.j2ee.metadata.model.api.MetadataModelAction;
import org.openide.filesystems.FileObject;
import org.openide.util.Exceptions;
public class Utils {
public static String toClasspathString(File[] classpathEntries) {
if (classpathEntries == null) {
return "";
}
StringBuffer classpath = new StringBuffer();
for (int i = 0; i < classpathEntries.length; i++) {
classpath.append(classpathEntries[i].getAbsolutePath());
if (i + 1 < classpathEntries.length) {
classpath.append(':');
}
}
return classpath.toString();
}
public static void notifyError(Exception exception) {
NotifyDescriptor ndd = new NotifyDescriptor.Message(exception.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(ndd);
}
public static boolean areInSameJ2EEApp(Project project1, Project project2) {
Project[] openProjects = OpenProjects.getDefault().getOpenProjects();
for (int i = 0; i < openProjects.length; i++) {
Project project = openProjects[i];
Object j2eeAppProvider = project.getLookup().lookup(J2eeApplicationProvider.class);
if (j2eeAppProvider != null) { // == it is j2ee app
J2eeApplicationProvider j2eeApp = (J2eeApplicationProvider)j2eeAppProvider;
J2eeModuleProvider[] j2eeModules = j2eeApp.getChildModuleProviders();
if ((j2eeModules != null) && (j2eeModules.length > 0)) { // == there are some modules in the j2ee app
J2eeModuleProvider affectedPrjProvider1 = project1.getLookup().lookup(J2eeModuleProvider.class);
J2eeModuleProvider affectedPrjProvider2 = project2.getLookup().lookup(J2eeModuleProvider.class);
if (affectedPrjProvider1 != null && affectedPrjProvider2 != null) {
List childModules = Arrays.asList(j2eeModules);
if (childModules.contains(affectedPrjProvider1) &&
childModules.contains(affectedPrjProvider2)) {
return true;
}
}
}
}
}
return false;
}
/**
* Returns true if j2eeModuleProvider is part of some open J2EE application
*/
public static boolean isPartOfJ2eeApp(J2eeModuleProvider j2eeModuleProvider) {
for (Project openProject : OpenProjects.getDefault().getOpenProjects()) {
J2eeApplicationProvider j2eeAppProvider = openProject.getLookup().lookup(J2eeApplicationProvider.class);
if (j2eeAppProvider != null) {
if (Arrays.asList(j2eeAppProvider.getChildModuleProviders()).contains(j2eeModuleProvider)) {
return true;
}
}
}
return false;
}
public static Project getNestingJ2eeApp(Project project){
J2eeModuleProvider j2eeModuleProvider = project.getLookup().lookup(J2eeModuleProvider.class);
for (Project openProject : OpenProjects.getDefault().getOpenProjects()) {
J2eeApplicationProvider j2eeAppProvider = openProject.getLookup().lookup(J2eeApplicationProvider.class);
if (j2eeAppProvider != null) {
if (Arrays.asList(j2eeAppProvider.getChildModuleProviders()).contains(j2eeModuleProvider)) {
return openProject;
}
}
}
return null;
}
// =========================================================================
// utils for ejb code synchronization
public static boolean canExposeInLocal(FileObject ejbClassFO, final ElementHandle<ExecutableElement> methodHandle) throws IOException {
JavaSource javaSource = JavaSource.forFileObject(ejbClassFO);
final String[] ejbClassName = new String[1];
final MethodModel[] methodModel = new MethodModel[1];
javaSource.runModificationTask(new Task<WorkingCopy>() {
public void run(WorkingCopy workingCopy) throws IOException {
workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
ExecutableElement executableElement = methodHandle.resolve(workingCopy);
Set<Modifier> modifiers = executableElement.getModifiers();
boolean signatureOk = modifiers.contains(Modifier.PUBLIC) && !modifiers.contains(Modifier.STATIC);
if (signatureOk) {
Element enclosingElement = executableElement.getEnclosingElement();
ejbClassName[0] = ((TypeElement) enclosingElement).getQualifiedName().toString();
methodModel[0] = MethodModelSupport.createMethodModel(workingCopy, executableElement);
}
}
});
if (methodModel[0] != null) {
EjbMethodController ejbMethodController = EjbMethodController.createFromClass(ejbClassFO, ejbClassName[0]);
return ejbMethodController != null && ejbMethodController.hasLocal() && !ejbMethodController.hasMethodInInterface(methodModel[0], ejbMethodController.getMethodTypeFromImpl(methodModel[0]), true);
}
return false;
}
public static void exposeInLocal(FileObject ejbClassFO, final ElementHandle<ExecutableElement> methodHandle) throws IOException {
JavaSource javaSource = JavaSource.forFileObject(ejbClassFO);
final String[] ejbClassName = new String[1];
final MethodModel[] methodModel = new MethodModel[1];
javaSource.runModificationTask(new Task<WorkingCopy>() {
public void run(WorkingCopy workingCopy) throws IOException {
workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
ExecutableElement method = methodHandle.resolve(workingCopy);
Element enclosingElement = method.getEnclosingElement();
ejbClassName[0] = ((TypeElement) enclosingElement).getQualifiedName().toString();
methodModel[0] = MethodModelSupport.createMethodModel(workingCopy, method);
}
});
if (methodModel[0] != null) {
EjbMethodController ejbMethodController = EjbMethodController.createFromClass(ejbClassFO, ejbClassName[0]);
ejbMethodController.createAndAddInterface(methodModel[0], true);
}
}
public static boolean canExposeInRemote(FileObject ejbClassFO, final ElementHandle<ExecutableElement> methodHandle) throws IOException {
JavaSource javaSource = JavaSource.forFileObject(ejbClassFO);
final String[] ejbClassName = new String[1];
final MethodModel[] methodModel = new MethodModel[1];
javaSource.runModificationTask(new Task<WorkingCopy>() {
public void run(WorkingCopy workingCopy) throws IOException {
workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
ExecutableElement executableElement = methodHandle.resolve(workingCopy);
Set<Modifier> modifiers = executableElement.getModifiers();
boolean signatureOk = modifiers.contains(Modifier.PUBLIC) && !modifiers.contains(Modifier.STATIC);
if (signatureOk) {
Element enclosingElement = executableElement.getEnclosingElement();
ejbClassName[0] = ((TypeElement) enclosingElement).getQualifiedName().toString();
methodModel[0] = MethodModelSupport.createMethodModel(workingCopy, executableElement);
}
}
});
if (methodModel[0] != null) {
EjbMethodController ejbMethodController = EjbMethodController.createFromClass(ejbClassFO, ejbClassName[0]);
return ejbMethodController != null && ejbMethodController.hasRemote() && !ejbMethodController.hasMethodInInterface(methodModel[0], ejbMethodController.getMethodTypeFromImpl(methodModel[0]), true);
}
return false;
}
public static void exposeInRemote(FileObject ejbClassFO, final ElementHandle<ExecutableElement> methodHandle) throws IOException {
JavaSource javaSource = JavaSource.forFileObject(ejbClassFO);
final String[] ejbClassName = new String[1];
final MethodModel[] methodModel = new MethodModel[1];
javaSource.runModificationTask(new Task<WorkingCopy>() {
public void run(WorkingCopy workingCopy) throws IOException {
workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
ExecutableElement method = methodHandle.resolve(workingCopy);
Element enclosingElement = method.getEnclosingElement();
ejbClassName[0] = ((TypeElement) enclosingElement).getQualifiedName().toString();
methodModel[0] = MethodModelSupport.createMethodModel(workingCopy, method);
}
});
if (methodModel[0] != null) {
EjbMethodController ejbMethodController = EjbMethodController.createFromClass(ejbClassFO, ejbClassName[0]);
ejbMethodController.createAndAddInterface(methodModel[0], false);
}
}
/** Returns list of all EJB projects that can be called from the caller project.
*
* @param enterpriseProject the caller enterprise project
*/
public static Project [] getCallableEjbProjects(Project enterpriseProject) {
Project[] allProjects = OpenProjects.getDefault().getOpenProjects();
// TODO: HACK - this must be solved by freeform's own implementation of EnterpriseReferenceContainer, see issue 57003
// call ejb should not make this check, all should be handled in EnterpriseReferenceContainer
boolean isCallerFreeform = enterpriseProject.getClass().getName().equals("org.netbeans.modules.ant.freeform.FreeformProject");
boolean isCallerEE6WebProject = isEE6WebProject(enterpriseProject);
List<Project> filteredResults = new ArrayList<Project>(allProjects.length);
for (int i = 0; i < allProjects.length; i++) {
boolean isEJBModule = false;
J2eeModuleProvider j2eeModuleProvider = allProjects[i].getLookup().lookup(J2eeModuleProvider.class);
if (j2eeModuleProvider != null){
Type type = j2eeModuleProvider.getJ2eeModule().getType();
EjbJar[] ejbJars = EjbJar.getEjbJars(allProjects[i]);
Profile profile = ejbJars.length > 0 ? ejbJars[0].getJ2eeProfile() : null;
if (J2eeModule.Type.EJB.equals(type) || (J2eeModule.Type.WAR.equals(type) &&
(Profile.JAVA_EE_6_WEB.equals(profile) || Profile.JAVA_EE_6_FULL.equals(profile) ||
Profile.JAVA_EE_7_WEB.equals(profile) || Profile.JAVA_EE_7_FULL.equals(profile) ||
Profile.JAVA_EE_8_WEB.equals(profile) || Profile.JAVA_EE_8_FULL.equals(profile)))){
isEJBModule = true;
}
}
// If the caller project is NOT a freeform project, include all EJB modules
// If the caller project is a freeform project, include caller itself only
// If the caller project is a Java EE 6 web project, include itself in the list
if ((isEJBModule && !isCallerFreeform) ||
(enterpriseProject.equals(allProjects[i]) && (isCallerFreeform || isCallerEE6WebProject) ) ) {
filteredResults.add(allProjects[i]);
}
}
return filteredResults.toArray(new Project[filteredResults.size()]);
}
public static boolean isEE6WebProject(Project enterpriseProject) {
return J2eeProjectCapabilities.forProject(enterpriseProject).isEjb31LiteSupported();
}
public static boolean isAppClient(Project project) {
J2eeModuleProvider module = project.getLookup().lookup(J2eeModuleProvider.class);
return (module != null) ? module.getJ2eeModule().getType().equals(J2eeModule.Type.CAR) : false;
}
/**
* Checks if the target is Java SE class.
* <p>
* <i>Note: Should run outside EDT!</i>
* @return true if given <code>target</code> is defined in a Java SE environment.
*/
public static boolean isTargetJavaSE(FileObject fileObject, final String className) throws IOException{
Project owner = FileOwnerQuery.getOwner(fileObject);
if (owner.getLookup().lookup(J2eeModuleProvider.class) == null){
return true;
}
JavaSource javaSource = JavaSource.forFileObject(fileObject);
if (javaSource == null) {
return false;
}
final boolean[] result = new boolean[] { false };
javaSource.runUserActionTask(new Task<CompilationController>() {
public void run(CompilationController controller) throws IOException {
controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
TypeElement typeElement = controller.getElements().getTypeElement(className);
TypeElement junitTestCase = controller.getElements().getTypeElement("junit.framework.TestCase");
if (junitTestCase != null && typeElement != null) {
result[0] = controller.getTypes().isSubtype(typeElement.asType(), junitTestCase.asType());
}
}
}, true);
return result[0];
}
// /**
// * @return true if given <code>javaClass</code> is a subtype (direct or
// * indirect) of <code>junit.framework.TestCase</code>.
// */
// private static boolean extendsTestCase(CompilationController controller, TypeElement typeElement){
// if (typeElement == null){
// return false;
// }
// if (typeElement.getQualifiedName().contentEquals("junit.framework.TestCase")){
// return true;
// }
// DeclaredType superClassType = (DeclaredType) typeElement.getSuperclass();
// return extendsTestCase(controller, (TypeElement) superClassType.asElement());
// }
/**
* Converts the given <code>jndiName</code> to camel case, i.e. removes
* all <code>/</code> characters and converts characters to upper case appropriately.
* For example, returns <code>SomeJndiName</code> for <code>some/jndi/name</code> or
* <code>someJndiName</code> if <code>lowerCaseFirstChar</code> is true.
* @param jndiName the JNDI name to convert; must not be null.
* @param lowerCaseFirstChar defines whether the first char of the resulting name
* should be lower case (note that if all chars of the given <code>jndiName</code> are
* uppercase characters, its first char will not be converted to lower case even
* if this param is true).
* @param prefixToStrip the prefix that will be stripped from the resulting name. If null,
* nothing will be stripped.
* @return String representing the converted name.
*/
public static String jndiNameToCamelCase(String jndiName, boolean lowerCaseFirstChar, String prefixToStrip){
String strippedJndiName = jndiName;
if (prefixToStrip != null && jndiName.startsWith(prefixToStrip)){
strippedJndiName = jndiName.substring(jndiName.indexOf(prefixToStrip) + prefixToStrip.length());
}
StringBuilder result = new StringBuilder();
for (String token : strippedJndiName.split("/")){
if (token.length() == 0){
continue;
}
char firstChar = token.charAt(0);
if (lowerCaseFirstChar && result.length() == 0 && !isAllUpperCase(token)){
firstChar = Character.toLowerCase(firstChar);
} else {
firstChar = Character.toUpperCase(firstChar);
}
result.append(firstChar);
result.append(token.substring(1));
}
return result.toString();
}
public static String makeJavaIdentifierPart(String identifier){
StringBuilder result = new StringBuilder(identifier.length());
for (int i = 0; i < identifier.length(); i++){
if (Character.isJavaIdentifierPart(identifier.charAt(i))){
result.append(identifier.charAt(i));
} else {
result.append('_');
}
}
return result.toString();
}
public static Project getProject(final EjbReference ejbReference, final EjbReference.EjbRefIType refIType) throws IOException {
FileObject ejbReferenceEjbClassFO = ejbReference.getComponentFO(refIType);
return ejbReferenceEjbClassFO != null ? FileOwnerQuery.getOwner(ejbReferenceEjbClassFO) : null;
}
/**
* Creates resource name from fully-qualified class name by
* replacing '.' with '/' and appending ".java"
*/
public static String toResourceName(String className) {
assert className != null: "cannot find null className";
return className.replace('.', '/') + ".java";
}
/**
* @return true if the given <code>str</code> has more than one char
* and all its chars are uppercase, false otherwise.
*/
private static boolean isAllUpperCase(String str){
if (str.length() <= 1){
return false;
}
for (char c : str.toCharArray()) {
if (Character.isLowerCase(c)){
return false;
}
}
return true;
}
public static String getBeanType(final EjbReference ref) throws IOException{
String type = ref.getEjbModule().getMetadataModel().runReadAction(new MetadataModelAction<EjbJarMetadata, String>(){
public String run(EjbJarMetadata metadata) throws Exception {
Session[] sessionEJBs = metadata.getRoot().getEnterpriseBeans().getSession();
for(Session session: sessionEJBs){
if (session.getEjbClass().equals(ref.getEjbClass())){
return session.getSessionType();
}
}
return null;
}
});
return type;
}
public static boolean isServlet(FileObject fileObject, final String className){
final boolean[] result = new boolean[]{false};
try {
JavaSource js = JavaSource.forFileObject(fileObject);
js.runUserActionTask(new Task<CompilationController>() {
public void run(CompilationController cc) throws Exception {
cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
TypeElement typeElement = cc.getElements().getTypeElement(className);
TypeElement servletTypeElement = cc.getElements().getTypeElement("javax.servlet.Servlet"); //NOI18N
if (typeElement != null && servletTypeElement != null) {
result[0] = cc.getTypes().isSubtype(typeElement.asType(), servletTypeElement.asType());
}
}
}, true);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return result[0];
}
public static ClassPath getCompileClassPath(Project project) {
SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
if (sourceGroups.length > 0) {
FileObject sourceGroupRoot = sourceGroups[0].getRootFolder();
ClassPath classPath = ClassPath.getClassPath(sourceGroupRoot, ClassPath.COMPILE);
return classPath;
}
return null;
}
public static boolean removeLibraryFromClasspath(Project project, Library... libraries) throws IOException {
boolean result = false;
SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
for (SourceGroup sourceGroup : sourceGroups) {
boolean cpChange = ProjectClassPathModifier.removeLibraries(
libraries,
sourceGroup.getRootFolder(),
JavaClassPathConstants.COMPILE_ONLY);
if (cpChange) {
result = true;
}
}
return result;
}
public static void addLibraryToClasspath(Project project, Library... libraries) throws IOException {
SourceGroup[] sourceGroups = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
for (SourceGroup sourceGroup : sourceGroups) {
ProjectClassPathModifier.addLibraries(
libraries,
sourceGroup.getRootFolder(),
JavaClassPathConstants.COMPILE_ONLY);
}
}
// public static ExecutableElement[] getMethods(EjbMethodController c, boolean checkLocal, boolean checkRemote) {
// List<ExecutableElement> methods = new ArrayList<ExecutableElement>();
// List features;
// for (ExecutableElement method : ElementFilter.methodsIn(c.getBeanClass().getEnclosedElements())) {
// methods.add(method);
// }
// if (checkLocal) {
// for (TypeElement interfaceCE : c.getLocalInterfaces()) {
// for (ExecutableElement method : ElementFilter.methodsIn(interfaceCE.getEnclosedElements())) {
// methods.add(method);
// }
// }
// }
// if (checkRemote) {
// for (TypeElement interfaceCE : c.getRemoteInterfaces()) {
// for (ExecutableElement method : ElementFilter.methodsIn(interfaceCE.getEnclosedElements())) {
// methods.add(method);
// }
// }
// }
// ExecutableElement[] methodsArray = methods.toArray(new ExecutableElement[methods.size()]);
// return methodsArray;
// }
}