All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.persist.impl.EnhancedAccessor Maven / Gradle / Ivy

There is a newer version: 18.3.12
Show newest version
/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 2002, 2013 Oracle and/or its affiliates.  All rights reserved.
 *
 */

package com.sleepycat.persist.impl;

import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sleepycat.compat.DbCompat;

/**
 * Implements Accessor for a complex persistent class.
 *
 * @author Mark Hayes
 */
public class EnhancedAccessor implements Accessor {

    private static final Map classRegistry =
        Collections.synchronizedMap(new HashMap());

    /* Is public for unit tests. */
    public static final boolean EXPECT_ENHANCED =
        "true".equals(System.getProperty("expectEnhanced"));

    private Enhanced prototype;
    private Format priKeyFormat;
    private Format[] compositeKeyFormats; 
    private Class type;

    /**
     * Registers a prototype instance, and should be called during
     * initialization of the prototype class.  The prototype may be null for
     * an abstract class.
     */
    public static void registerClass(String className, Enhanced prototype) {
        classRegistry.put(className, prototype);
    }

    /**
     * Returns whether a given class is a (registered) enhanced class.
     */
    static boolean isEnhanced(Class type) {
        boolean enhanced = classRegistry.containsKey(type.getName());
        if (!enhanced && EXPECT_ENHANCED) {
            throw new IllegalStateException
                ("Test was run with expectEnhanced=true but class " +
                 type.getName() + " is not enhanced");
        }
        return enhanced;
    }

    private EnhancedAccessor(Class type) {
        this.type = type;
        prototype = classRegistry.get(type.getName());
        assert prototype != null || Modifier.isAbstract(type.getModifiers());
    }

    /**
     * Creates an accessor for a complex type.
     */
    EnhancedAccessor(Catalog catalog, Class type, ComplexFormat format) {
        this(type);

        /*
         * Find the primary key format for this format or one of its superclass
         * formats.
         */
        ComplexFormat declaringFormat = format;
        while (declaringFormat != null) {
            FieldInfo priKeyField = declaringFormat.getPriKeyFieldInfo();
            if (priKeyField != null) {
                priKeyFormat = catalog.getFormat(priKeyField.getClassName());
                break;
            } else {
                declaringFormat = declaringFormat.getComplexSuper();
            }
        }
    }

    /**
     * Creates an accessor for a composite key type.
     */
    EnhancedAccessor(Catalog catalog, Class type, List fieldInfos) {
        this(type);
        final int nFields = fieldInfos.size();
        compositeKeyFormats = new Format[nFields];
        for (int i = 0; i < nFields; i += 1) {
            compositeKeyFormats[i] =
                catalog.getFormat(fieldInfos.get(i).getClassName());
        }
    }

    public Object newInstance() {
        if (prototype == null) {
            /* Abstract class -- internal error. */
            throw DbCompat.unexpectedState();
        }
        return prototype.bdbNewInstance();
    }

    public Object newArray(int len) {
        if (prototype == null) {
            /* Abstract class -- use reflection for now. */
            return Array.newInstance(type, len);
        }
        return prototype.bdbNewArray(len);
    }

    public boolean isPriKeyFieldNullOrZero(Object o) {
        if (priKeyFormat == null) {
            throw DbCompat.unexpectedState
                ("No primary key: " + o.getClass().getName());
        }
        return ((Enhanced) o).bdbIsPriKeyFieldNullOrZero();
    }

    public void writePriKeyField(Object o, EntityOutput output)
        throws RefreshException {

        if (priKeyFormat == null) {
            throw DbCompat.unexpectedState
                ("No primary key: " + o.getClass().getName());
        }
        ((Enhanced) o).bdbWritePriKeyField(output, priKeyFormat);
    }

    public void readPriKeyField(Object o, EntityInput input)
        throws RefreshException {

        if (priKeyFormat == null) {
            throw DbCompat.unexpectedState
                ("No primary key: " + o.getClass().getName());
        }
        ((Enhanced) o).bdbReadPriKeyField(input, priKeyFormat);
    }

    public void writeSecKeyFields(Object o, EntityOutput output)
        throws RefreshException {

        ((Enhanced) o).bdbWriteSecKeyFields(output);
    }

    public void readSecKeyFields(Object o,
                                 EntityInput input,
                                 int startField,
                                 int endField,
                                 int superLevel)
        throws RefreshException {

        ((Enhanced) o).bdbReadSecKeyFields
            (input, startField, endField, superLevel);
    }

    public void writeNonKeyFields(Object o, EntityOutput output)
        throws RefreshException {

        ((Enhanced) o).bdbWriteNonKeyFields(output);
    }

    public void readNonKeyFields(Object o,
                                 EntityInput input,
                                 int startField,
                                 int endField,
                                 int superLevel)
        throws RefreshException {

        ((Enhanced) o).bdbReadNonKeyFields
            (input, startField, endField, superLevel);
    }

    public void writeCompositeKeyFields(Object o, EntityOutput output)
        throws RefreshException {

        ((Enhanced) o).bdbWriteCompositeKeyFields(output, compositeKeyFormats);
    }

    public void readCompositeKeyFields(Object o, EntityInput input)
        throws RefreshException {

        ((Enhanced) o).bdbReadCompositeKeyFields(input, compositeKeyFormats);
    }

    public Object getField(Object o,
                           int field,
                           int superLevel,
                           boolean isSecField) {
        return ((Enhanced) o).bdbGetField(o, field, superLevel, isSecField);
    }

    public void setField(Object o,
                         int field,
                         int superLevel,
                         boolean isSecField,
                         Object value) {
        ((Enhanced) o).bdbSetField(o, field, superLevel, isSecField, value);
    }
    
    public void setPriField(Object o, Object value) {
        ((Enhanced) o).bdbSetPriField(o, value);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy