/* * Copyright 2013 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.widgets.client.datamodel; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.drools.workbench.models.datamodel.imports.Import; import org.drools.workbench.models.datamodel.imports.Imports; import org.drools.workbench.models.datamodel.oracle.Annotation; import org.drools.workbench.models.datamodel.oracle.MethodInfo; import org.drools.workbench.models.datamodel.oracle.ModelField; import org.drools.workbench.models.datamodel.oracle.TypeSource; import org.kie.workbench.common.services.datamodel.model.LazyModelField; import org.kie.workbench.common.services.datamodel.model.PackageDataModelOracleIncrementalPayload; public class AsyncPackageDataModelOracleUtilities { public static void populateDataModelOracle( final AsyncPackageDataModelOracle oracle, final PackageDataModelOracleIncrementalPayload payload ) { if ( payload == null ) { return; } populate( oracle, payload ); oracle.filter(); } private static void populate( final AsyncPackageDataModelOracle oracle, final PackageDataModelOracleIncrementalPayload payload ) { oracle.addModelFields( payload.getModelFields() ); oracle.addFieldParametersType( payload.getFieldParametersType() ); oracle.addEventTypes( payload.getEventTypes() ); oracle.addTypeSources( payload.getTypeSources() ); oracle.addSuperTypes( payload.getSuperTypes() ); oracle.addTypeAnnotations( payload.getTypeAnnotations() ); oracle.addTypeFieldsAnnotations( payload.getTypeFieldsAnnotations() ); oracle.addMethodInformation( payload.getMethodInformation() ); oracle.addCollectionTypes( payload.getCollectionTypes() ); } //Filter and rename Model Fields based on package name and imports public static Map<String, ModelField[]> filterModelFields( final String packageName, final Imports imports, final Map<String, ModelField[]> projectModelFields, final FactNameToFQCNHandleRegistry registry ) { final Map<String, ModelField[]> scopedModelFields = new HashMap<String, ModelField[]>(); for ( Map.Entry<String, ModelField[]> entry : projectModelFields.entrySet() ) { final String mfQualifiedType = entry.getKey(); final String mfPackageName = getPackageName( mfQualifiedType ); final String mfTypeName = getTypeName( mfQualifiedType ); if ( registry.contains( mfTypeName ) ) { // Override existing final Set<String> importStrings = imports.getImportStrings(); if ( mfPackageName.equals( packageName ) || importStrings.contains( mfQualifiedType ) ) { registry.add( mfTypeName, mfQualifiedType ); } } else { registry.add( mfTypeName, mfQualifiedType ); } if ( mfPackageName.equals( packageName ) || isImported( mfQualifiedType, imports ) ) { scopedModelFields.put( mfTypeName, correctModelFields( packageName, entry.getValue(), imports ) ); } } return scopedModelFields; } //Filter and rename Collection Types based on package name and imports public static Map<String, Boolean> filterCollectionTypes( final String packageName, final Imports imports, final Map<String, Boolean> projectCollectionTypes ) { final Map<String, Boolean> scopedCollectionTypes = new HashMap<String, Boolean>(); for ( Map.Entry<String, Boolean> e : projectCollectionTypes.entrySet() ) { final String collectionQualifiedType = e.getKey(); final String collectionPackageName = getPackageName( collectionQualifiedType ); final String collectionTypeName = getTypeName( collectionQualifiedType ); if ( collectionPackageName.equals( packageName ) || isImported( collectionQualifiedType, imports ) ) { scopedCollectionTypes.put( collectionTypeName, e.getValue() ); } } return scopedCollectionTypes; } //Filter and rename Global Types based on package name and imports public static Map<String, String> filterGlobalTypes( final String packageName, final Imports imports, final Map<String, String> packageGlobalTypes ) { final Map<String, String> scopedGlobalTypes = new HashMap<String, String>(); for ( Map.Entry<String, String> e : packageGlobalTypes.entrySet() ) { final String globalQualifiedType = e.getValue(); final String globalPackageName = getPackageName( globalQualifiedType ); final String globalTypeName = getTypeName( globalQualifiedType ); if ( globalPackageName.equals( packageName ) || isImported( globalQualifiedType, imports ) ) { scopedGlobalTypes.put( e.getKey(), globalTypeName ); } } return scopedGlobalTypes; } //Filter and rename Event Types based on package name and imports public static Map<String, Boolean> filterEventTypes( final String packageName, final Imports imports, final Map<String, Boolean> projectEventTypes ) { final Map<String, Boolean> scopedEventTypes = new HashMap<String, Boolean>(); for ( Map.Entry<String, Boolean> e : projectEventTypes.entrySet() ) { final String eventQualifiedType = e.getKey(); final String eventPackageName = getPackageName( eventQualifiedType ); final String eventTypeName = getTypeName( eventQualifiedType ); if ( eventPackageName.equals( packageName ) || isImported( eventQualifiedType, imports ) ) { scopedEventTypes.put( eventTypeName, e.getValue() ); } } return scopedEventTypes; } //Filter and rename TypeSource based on package name and imports public static Map<String, TypeSource> filterTypeSources( final String packageName, final Imports imports, final Map<String, TypeSource> projectTypeSources ) { final Map<String, TypeSource> scopedTypeSources = new HashMap<String, TypeSource>(); for ( Map.Entry<String, TypeSource> e : projectTypeSources.entrySet() ) { final String typeQualifiedType = e.getKey(); final String typePackageName = getPackageName( typeQualifiedType ); final String typeTypeName = getTypeName( typeQualifiedType ); if ( typePackageName.equals( packageName ) || isImported( typeQualifiedType, imports ) ) { scopedTypeSources.put( typeTypeName, e.getValue() ); } } return scopedTypeSources; } //Filter and rename Super Types based on package name and imports public static Map<String, List<String>> filterSuperTypes( final String packageName, final Imports imports, final Map<String, List<String>> projectSuperTypes ) { final Map<String, List<String>> scopedSuperTypes = new HashMap<String, List<String>>(); for ( Map.Entry<String, List<String>> e : projectSuperTypes.entrySet() ) { final String typeQualifiedType = e.getKey(); final String typePackageName = getPackageName( typeQualifiedType ); final String typeTypeName = getTypeName( typeQualifiedType ); final List<String> superTypeQualifiedTypes = e.getValue(); if ( superTypeQualifiedTypes == null ) { //Doesn't have a Super Type if ( typePackageName.equals( packageName ) || isImported( typeQualifiedType, imports ) ) { scopedSuperTypes.put( typeTypeName, superTypeQualifiedTypes ); } } else { //Has a Super Type if ( typePackageName.equals( packageName ) || isImported( typeQualifiedType, imports ) ) { ArrayList<String> result = new ArrayList<String>(); for ( String superTypeQualifiedType : superTypeQualifiedTypes ) { final String superTypePackageName = getPackageName( superTypeQualifiedType ); final String superTypeTypeName = getTypeName( superTypeQualifiedType ); if ( superTypePackageName.equals( packageName ) || isImported( superTypeQualifiedType, imports ) ) { result.add( superTypeTypeName ); } else { result.add( superTypeQualifiedType ); } } scopedSuperTypes.put( typeTypeName, result ); } } } return scopedSuperTypes; } //Filter and rename Type Annotations based on package name and imports public static Map<String, Set<Annotation>> filterTypeAnnotations( final String packageName, final Imports imports, final Map<String, Set<Annotation>> projectTypeAnnotations ) { final Map<String, Set<Annotation>> scopedTypeAnnotations = new HashMap<String, Set<Annotation>>(); for ( Map.Entry<String, Set<Annotation>> e : projectTypeAnnotations.entrySet() ) { final String typeAnnotationQualifiedType = e.getKey(); final String typeAnnotationPackageName = getPackageName( typeAnnotationQualifiedType ); final String typeAnnotationTypeName = getTypeName( typeAnnotationQualifiedType ); if ( typeAnnotationPackageName.equals( packageName ) || isImported( typeAnnotationQualifiedType, imports ) ) { scopedTypeAnnotations.put( typeAnnotationTypeName, e.getValue() ); } } return scopedTypeAnnotations; } //Filter and rename Type Fields Annotations based on package name and imports public static Map<String, Map<String, Set<Annotation>>> filterTypeFieldsAnnotations( final String packageName, final Imports imports, final Map<String, Map<String, Set<Annotation>>> projectTypeFieldsAnnotations ) { final Map<String, Map<String, Set<Annotation>>> scopedTypeFieldsAnnotations = new HashMap<String, Map<String, Set<Annotation>>>(); for ( Map.Entry<String, Map<String, Set<Annotation>>> e : projectTypeFieldsAnnotations.entrySet() ) { final String typeAnnotationQualifiedType = e.getKey(); final String typeAnnotationPackageName = getPackageName( typeAnnotationQualifiedType ); final String typeAnnotationTypeName = getTypeName( typeAnnotationQualifiedType ); if ( typeAnnotationPackageName.equals( packageName ) || isImported( typeAnnotationQualifiedType, imports ) ) { scopedTypeFieldsAnnotations.put( typeAnnotationTypeName, e.getValue() ); } } return scopedTypeFieldsAnnotations; } //Filter and rename Enum definitions based on package name and imports public static Map<String, String[]> filterEnumDefinitions( final String packageName, final Imports imports, final Map<String, String[]> enumDefinitions ) { final Map<String, String[]> scopedEnumLists = new HashMap<String, String[]>(); for ( Map.Entry<String, String[]> e : enumDefinitions.entrySet() ) { final String enumQualifiedType = getQualifiedTypeFromEnumeration( e.getKey() ); final String enumFieldName = getFieldNameFromEnumeration( e.getKey() ); final String enumPackageName = getPackageName( enumQualifiedType ); final String enumTypeName = getTypeName( enumQualifiedType ); if ( enumPackageName.equals( packageName ) || isImported( enumQualifiedType, imports ) ) { scopedEnumLists.put( enumTypeName + "#" + enumFieldName, e.getValue() ); } } return scopedEnumLists; } // For filling the FQCN-fact name registry public static void visitMethodInformation( final Map<String, List<MethodInfo>> projectMethodInformation, final FactNameToFQCNHandleRegistry registry ) { for ( Map.Entry<String, List<MethodInfo>> e : projectMethodInformation.entrySet() ) { final String miQualifiedType = e.getKey(); final String miTypeName = getTypeName( miQualifiedType ); registry.add( miTypeName, miQualifiedType ); } } //Filter and rename Field Parameter Types based on package name and imports public static Map<String, String> filterFieldParametersTypes( final String packageName, final Imports imports, final Map<String, String> projectFieldParametersTypes ) { final Map<String, String> scopedFieldParametersType = new HashMap<String, String>(); for ( Map.Entry<String, String> e : projectFieldParametersTypes.entrySet() ) { String fieldName = e.getKey(); String fieldType = e.getValue(); final String fFieldName = getFieldNameFromEnumeration( fieldName ); final String fFieldName_QualifiedType = getQualifiedTypeFromEnumeration( fieldName ); final String fFieldName_PackageName = getPackageName( fFieldName_QualifiedType ); final String fFieldName_TypeName = getTypeName( fFieldName_QualifiedType ); if ( fFieldName_PackageName.equals( packageName ) || isImported( fFieldName_QualifiedType, imports ) ) { fieldName = fFieldName_TypeName; } final String fFieldType_QualifiedType = getQualifiedTypeFromEnumeration( fieldType ); final String fFieldType_PackageName = getPackageName( fFieldType_QualifiedType ); final String fFieldType_TypeName = getTypeName( fFieldType_QualifiedType ); if ( fFieldType_PackageName.equals( packageName ) || isImported( fFieldType_QualifiedType, imports ) ) { fieldType = fFieldType_TypeName; } scopedFieldParametersType.put( fieldName + "#" + fFieldName, fieldType ); } return scopedFieldParametersType; } public static String getPackageName( final String qualifiedType ) { String packageName = qualifiedType; int dotIndex = packageName.lastIndexOf( "." ); if ( dotIndex != -1 ) { return packageName.substring( 0, dotIndex ); } return ""; } public static String getTypeName( final String qualifiedType ) { String typeName = qualifiedType; int dotIndex = typeName.lastIndexOf( "." ); if ( dotIndex != -1 ) { typeName = typeName.substring( dotIndex + 1 ); } if ( typeName.contains( "$" ) ) { typeName = typeName.replaceAll( "\\$", "." ); } return typeName; } private static String getQualifiedTypeFromEnumeration( final String qualifiedType ) { String typeName = qualifiedType; int hashIndex = typeName.lastIndexOf( "#" ); if ( hashIndex != -1 ) { typeName = typeName.substring( 0, hashIndex ); } return typeName; } private static String getFieldNameFromEnumeration( final String qualifiedType ) { String fieldName = qualifiedType; int hashIndex = fieldName.lastIndexOf( "#" ); if ( hashIndex != -1 ) { return fieldName.substring( hashIndex + 1 ); } return ""; } public static ModelField[] correctModelFields( final String packageName, final ModelField[] originalModelFields, final Imports imports ) { if ( originalModelFields == null ) { return null; } final List<ModelField> correctedModelFields = new ArrayList<ModelField>(); for ( final ModelField mf : originalModelFields ) { correctedModelFields.add( correctModelFields( packageName, imports, mf ) ); } final ModelField[] result = new ModelField[ correctedModelFields.size() ]; return correctedModelFields.toArray( result ); } public static ModelField correctModelFields( final String packageName, final Imports imports, final ModelField mf ) { String mfType = mf.getType(); String mfClassName = mf.getClassName(); final String mfClassName_QualifiedType = mfClassName; final String mfClassName_PackageName = getPackageName( mfClassName_QualifiedType ); final String mfClassName_TypeName = getTypeName( mfClassName_QualifiedType ); if ( mfClassName_PackageName.equals( packageName ) || isImported( mfClassName_QualifiedType, imports ) ) { mfClassName = mfClassName_TypeName; } final String mfType_QualifiedType = mfType; final String mfType_PackageName = getPackageName( mfType_QualifiedType ); final String mfType_TypeName = getTypeName( mfType_QualifiedType ); if ( mfType_PackageName.equals( packageName ) || isImported( mfType_QualifiedType, imports ) ) { mfType = mfType_TypeName; } return cloneModelField( mf, mfClassName, mfType ); } //Ensure we retain the LazyModelField information when filtering, as it's place-holder //for AsyncPackageDataModelOracle to know whether it needs to load additional information private static ModelField cloneModelField( final ModelField source, final String mfClassName, final String mfType ) { if ( source instanceof LazyModelField ) { return new LazyModelField( source.getName(), mfClassName, source.getClassType(), source.getOrigin(), source.getAccessorsAndMutators(), mfType ); } return new ModelField( source.getName(), mfClassName, source.getClassType(), source.getOrigin(), source.getAccessorsAndMutators(), mfType ); } public static MethodInfo correctMethodInformation( final String packageName, final MethodInfo originalMethodInformation, final Imports imports ) { final List<MethodInfo> correctedMethodInformation = correctMethodInformation( packageName, new ArrayList<MethodInfo>() {{ add( originalMethodInformation ); }}, imports ); if ( correctedMethodInformation == null || correctedMethodInformation.isEmpty() ) { return null; } return correctedMethodInformation.get( 0 ); } public static List<MethodInfo> correctMethodInformation( final String packageName, final List<MethodInfo> originalMethodInformation, final Imports imports ) { final List<MethodInfo> correctedMethodInformation = new ArrayList<MethodInfo>(); for ( final MethodInfo mi : originalMethodInformation ) { String miReturnType = mi.getReturnClassType(); String miGenericReturnType = mi.getGenericType(); String miParametricReturnType = mi.getParametricReturnType(); final String miReturnType_QualifiedType = miReturnType; final String miReturnType_PackageName = getPackageName( miReturnType_QualifiedType ); final String miReturnType_TypeName = getTypeName( miReturnType_QualifiedType ); if ( miReturnType_PackageName.equals( packageName ) || isImported( miReturnType_QualifiedType, imports ) ) { miReturnType = miReturnType_TypeName; } final String miGenericReturnType_QualifiedType = miGenericReturnType; final String miGenericReturnType_PackageName = getPackageName( miGenericReturnType_QualifiedType ); final String miGenericReturnType_TypeName = getTypeName( miGenericReturnType_QualifiedType ); if ( miGenericReturnType_PackageName.equals( packageName ) || isImported( miGenericReturnType_QualifiedType, imports ) ) { miGenericReturnType = miGenericReturnType_TypeName; } if ( miParametricReturnType != null ) { final String miParametricReturnType_QualifiedType = miParametricReturnType; final String miParametricReturnType_PackageName = getPackageName( miParametricReturnType_QualifiedType ); final String miParametricReturnType_TypeName = getTypeName( miParametricReturnType_QualifiedType ); if ( miParametricReturnType_PackageName.equals( packageName ) || isImported( miParametricReturnType_QualifiedType, imports ) ) { miParametricReturnType = miParametricReturnType_TypeName; } } correctedMethodInformation.add( new MethodInfo( mi.getName(), mi.getParams(), miReturnType, miParametricReturnType, miGenericReturnType ) ); } return correctedMethodInformation; } private static boolean isImported( final String qualifiedType, final Imports imports ) { final Import item = new Import( qualifiedType.replaceAll( "\\$", "." ) ); return imports.contains( item ); } }