/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * 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 * * 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.kie.workbench.common.services.backend.builder.core; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.drools.workbench.models.datamodel.oracle.TypeSource; import org.guvnor.common.services.project.builder.model.BuildMessage; import org.kie.scanner.KieModuleMetaData; import org.kie.workbench.common.services.shared.whitelist.WhiteList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.kie.workbench.common.services.backend.builder.core.BuildMessageBuilder.*; public class ClassVerifier { private static final Logger logger = LoggerFactory.getLogger( ClassVerifier.class ); private final static String ERROR_EXTERNAL_CLASS_VERIFICATION = "Verification of class {0} failed and will not be available for authoring.\n" + "Underlying system error is: {1}. Please check the necessary external dependencies for this project are configured correctly."; private final TypeSourceResolver typeSourceResolver; private final KieModuleMetaData kieModuleMetaData; private final List<BuildMessage> buildMessages = new ArrayList<BuildMessage>(); public ClassVerifier( final KieModuleMetaData kieModuleMetaData, final TypeSourceResolver typeSourceResolver ) { this.kieModuleMetaData = kieModuleMetaData; this.typeSourceResolver = typeSourceResolver; } public List<BuildMessage> verify( WhiteList whiteList ) { for (final String packageName : kieModuleMetaData.getPackages()) { if ( whiteList.contains( packageName ) ) { for (final String className : kieModuleMetaData.getClasses( packageName )) { verifyClass( packageName, className ); } } } return buildMessages; } private void verifyClass( final String packageName, final String className ) { try { final Class clazz = kieModuleMetaData.getClass( packageName, className ); if ( clazz != null ) { if ( TypeSource.JAVA_DEPENDENCY == typeSourceResolver.getTypeSource( clazz ) ) { verifyExternalClass( clazz ); } } else { logger.warn( MessageFormat.format( ERROR_EXTERNAL_CLASS_VERIFICATION, toFQCN( packageName, className ) ) ); } } catch (Throwable e) { final String msg = MessageFormat.format( ERROR_EXTERNAL_CLASS_VERIFICATION, toFQCN( packageName, className ), e.getMessage() ); logger.warn( msg ); logger.debug( "This state is usually encountered when the Project references a class not on the classpath; e.g. in a Maven 'provided' scope or 'optional' dependency.", e); buildMessages.add( makeWarningMessage( msg ) ); } } private String toFQCN( final String packageName, final String className ) { return packageName + "." + className; } private void verifyExternalClass( final Class clazz ) { //don't recommended to instantiate the class doing clazz.newInstance(). clazz.getDeclaredConstructors(); clazz.getDeclaredFields(); clazz.getDeclaredMethods(); clazz.getDeclaredClasses(); clazz.getDeclaredAnnotations(); } }