Package com.force.sdk.jpa.mock

Source Code of com.force.sdk.jpa.mock.MockPersistenceUtils

/**
* Copyright (c) 2011, salesforce.com, inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
*    Redistributions of source code must retain the above copyright notice, this list of conditions and the
*    following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*    the following disclaimer in the documentation and/or other materials provided with the distribution.
*
*    Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or
*    promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

package com.force.sdk.jpa.mock;

import static mockit.Deencapsulation.invoke;
import static mockit.Deencapsulation.newInstance;

import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Pattern;

import org.datanucleus.OMFContext;
import org.datanucleus.PersistenceConfiguration;
import org.datanucleus.jpa.metadata.JPAMetaDataManager;
import org.datanucleus.metadata.MetaDataManager;

import com.force.sdk.jpa.annotation.CustomField;
import com.force.sdk.jpa.annotation.CustomObject;
import com.force.sdk.jpa.table.*;
import com.sforce.soap.partner.Field;

/**
* A mocked PersistenceUtils class.
* <p>
* This class can construct a TableImpl using the
* @MockApiEntity, @MockApiField and @MockApiRelationship
* annotations.
*
* @author Tim Kral
*/
public final class MockPersistenceUtils {
   
    private static final Pattern BOOLEAN_PATTERN = Pattern.compile("(true|false)", Pattern.CASE_INSENSITIVE);
    private static final Pattern INTEGER_PATTERN = Pattern.compile("(\\d+)");
   
    private MockPersistenceUtils() {  }
   
    public static TableImpl constructTableImpl(Class<?> entityClass) {
       
        MockApiEntity mockEntityAnnotation;
        if ((mockEntityAnnotation = entityClass.getAnnotation(MockApiEntity.class)) == null) {
            throw new IllegalArgumentException("The class " + entityClass.getName()
                    + " must be annotated with @MockJPAEntity to be included in the mock framework.");
        }

        // State needed to build a TableImpl
        List<ColumnImpl> columnList = new ArrayList<ColumnImpl>();
        Map<String, ColumnImpl> forceApiColumns = new HashMap<String, ColumnImpl>();
        ColumnImpl externalId = null;
       
        Set<java.lang.reflect.Field> entityFields =
            new HashSet<java.lang.reflect.Field>(Arrays.<java.lang.reflect.Field>asList(entityClass.getDeclaredFields()));
       
        // Loop through the class hierarchy to load fields from super classes
        Class superClass = entityClass;
        while ((superClass = superClass.getSuperclass()) != null) {
            for (java.lang.reflect.Field superClassField : superClass.getDeclaredFields()) {
                int modifiers = superClassField.getModifiers();
               
                // Add public and protected fields from super classes
                if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) {
                    entityFields.add(superClassField);
                }
            }
        }
       
        for (java.lang.reflect.Field entityField : entityFields) {
            MockApiField mockFieldAnnotation;
            MockApiRelationship mockRelationshipAnnotation;
            ColumnImpl colImpl;
            String apiColumnKey;
            if ((mockFieldAnnotation = entityField.getAnnotation(MockApiField.class)) != null) {
           
                // Create an api field as described by @MockApiField
                Field apiField = new Field();
                apiField.setName(mockFieldAnnotation.name());
                apiField.setType(mockFieldAnnotation.type());
                apiField.setCustom(mockFieldAnnotation.custom());

                // Add any extra api field attributes
                // These should come in the form set<attrName>=attrValue
                for (String attr : mockFieldAnnotation.attrs()) {
                    String[] parsedAttr = attr.split("=", 2);
                    if (parsedAttr.length != 2)
                        throw new IllegalArgumentException("Could not parse api field attribute " + attr + ". "
                                + "It must be in the form 'set<attrName>=atrValue'");
                   
                    if (BOOLEAN_PATTERN.matcher(parsedAttr[1]).matches()) {
                        invoke(apiField, parsedAttr[0], Boolean.valueOf(parsedAttr[1]));
                    } else if (INTEGER_PATTERN.matcher(parsedAttr[1]).matches()) {
                        invoke(apiField, parsedAttr[0], Integer.valueOf(parsedAttr[1]));
                    } else {
                        // By default, treat as String argument
                        invoke(apiField, parsedAttr[0], parsedAttr[1]);
                    }
                }
               
                apiColumnKey = mockFieldAnnotation.name().toLowerCase();
                colImpl = new ColumnImpl(mockFieldAnnotation.name().toLowerCase(), apiField);
            } else if ((mockRelationshipAnnotation = entityField.getAnnotation(MockApiRelationship.class)) != null) {
                apiColumnKey = mockRelationshipAnnotation.name().toLowerCase();
                colImpl = new RelationshipImpl(mockRelationshipAnnotation.name());
            } else {
                continue;
            }
           
            columnList.add(colImpl);
            forceApiColumns.put(apiColumnKey, colImpl);
           
            // Set the externalId column
            if (entityField.isAnnotationPresent(CustomField.class)
                    && entityField.getAnnotation(CustomField.class).externalId()) {
                externalId = colImpl;
            }
        }
       
        // The default @MockApiEntity namespace is "" so treat this as null
        String namespace = null;
        if (!"".equals(mockEntityAnnotation.namespace())) {
            namespace = mockEntityAnnotation.namespace();
        }
        TableName tableName = newInstance(TableName.class, new Class[] {String.class, String.class, Boolean.TYPE},
                namespace, entityClass.getSimpleName().toLowerCase(), false /*parseForSuffix*/);
       
        // Construct TableImpl from non-public constructor
        return newInstance(TableImpl.class,
                           new Class[] {String.class, TableName.class, List.class, Map.class, ColumnImpl.class},
                                        namespace, tableName, columnList, forceApiColumns, externalId);
    }
   
    public static TableImpl constructVirtualTableImpl(Class<?> entityClass) {
        CustomObject customObjectAnnotation = entityClass.getAnnotation(CustomObject.class);
        if (customObjectAnnotation == null || !customObjectAnnotation.virtualSchema()) {
            throw new IllegalArgumentException("Trying to construct virtual schema for the class " + entityClass.getName()
                    + " but this class is not annotated as virtual schema.");
        }
       
        TableName tableName = newInstance(TableName.class, new Class[] {String.class, String.class, Boolean.TYPE},
                "" /*namespace*/, entityClass.getSimpleName().toLowerCase(), false /*parseForSuffix*/);
       
        // Construct a virtual TableImpl just like how the ForceStoreSchemaHandler would
        // (see ForceStoreSchemaHandler.addVirtualTable)
        OMFContext omfContext = new OMFContext(new PersistenceConfiguration() { });
        MetaDataManager metaDataManager = new JPAMetaDataManager(omfContext);
        return new TableImpl(tableName,
                             metaDataManager.getMetaDataForClass(entityClass, omfContext.getClassLoaderResolver(null)));
    }
}
TOP

Related Classes of com.force.sdk.jpa.mock.MockPersistenceUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.