summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceAccess.java
blob: 8633cc330ced26f4266438212832d2408a08dcbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright 2008-2012 Amazon Technologies, Inc. or its affiliates.
 * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
 * of Amazon Technologies, Inc. or its affiliates.  All rights reserved.
 *
 * 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 com.amazon.carbonado.synthetic;

import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;

import java.util.Comparator;
import java.util.Iterator;

import org.cojen.util.ThrowUnchecked;

import com.amazon.carbonado.FetchException;
import com.amazon.carbonado.Storable;

import com.amazon.carbonado.cursor.SortedCursor;

/**
 * Provides access to the generated storable reference class and utility
 * methods.
 *
 * @author Brian S O'Neill
 * @see SyntheticStorableReferenceBuilder
 * @since 1.2.1
 */
public class SyntheticStorableReferenceAccess<S extends Storable> {
    private final Class<S> mMasterClass;
    private final Class<? extends Storable> mReferenceClass;

    private final Comparator<? extends Storable> mComparator;

    private final Method mCopyFromMasterMethod;
    private final Method mIsConsistentMethod;
    private final Method mCopyToMasterPkMethod;

    SyntheticStorableReferenceAccess(Class<S> masterClass,
                                     Class<? extends Storable> referenceClass,
                                     SyntheticStorableReferenceBuilder builder)
    {
        mMasterClass = masterClass;
        mReferenceClass = referenceClass;

        // We need a comparator which follows the same order as the generated
        // storable.
        SyntheticKey pk = builder.mPrimaryKey;
        String[] orderBy = new String[pk.getPropertyCount()];
        int i=0;
        Iterator<String> it = pk.getProperties();
        while (it.hasNext()) {
            orderBy[i++] = it.next();
        }
        mComparator = SortedCursor.createComparator(referenceClass, orderBy);

        try {
            mCopyFromMasterMethod =
                referenceClass.getMethod(builder.mCopyFromMasterMethodName, masterClass);

            mIsConsistentMethod =
                referenceClass.getMethod(builder.mIsConsistentMethodName, masterClass);

            mCopyToMasterPkMethod =
                referenceClass.getMethod(builder.mCopyToMasterPkMethodName, masterClass);
        } catch (NoSuchMethodException e) {
            throw new UndeclaredThrowableException(e);
        }
    }

    /**
     * Returns the storable class which is referenced.
     */
    public Class<S> getMasterClass() {
        return mMasterClass;
    }

    /**
     * Returns the generated storable reference class.
     */
    public Class<? extends Storable> getReferenceClass() {
        return mReferenceClass;
    }

    /**
     * Returns a comparator for ordering storable reference instances. This
     * order matches the primary key of the master storable.
     */
    public Comparator<? extends Storable> getComparator() {
        return mComparator;
    }

    /**
     * Sets all the primary key properties of the given master, using the
     * applicable properties of the given reference.
     *
     * @param reference source of property values
     * @param master master whose primary key properties will be set
     */
    public void copyToMasterPrimaryKey(Storable reference, S master) throws FetchException {
        try {
            mCopyToMasterPkMethod.invoke(reference, master);
        } catch (Exception e) {
            ThrowUnchecked.fireFirstDeclaredCause(e, FetchException.class);
        }
    }

    /**
     * Sets all the properties of the given reference, using the applicable
     * properties of the given master.
     *
     * @param reference reference whose properties will be set
     * @param master source of property values
     */
    public void copyFromMaster(Storable reference, S master) throws FetchException {
        try {
            mCopyFromMasterMethod.invoke(reference, master);
        } catch (Exception e) {
            ThrowUnchecked.fireFirstDeclaredCause(e, FetchException.class);
        }
    }

    /**
     * Returns true if the properties of the given reference match those
     * contained in the master, excluding any version property. This will
     * always return true after a call to copyFromMaster.
     *
     * @param reference reference whose properties will be tested
     * @param master source of property values
     */
    public boolean isConsistent(Storable reference, S master) throws FetchException {
        try {
            return (Boolean) mIsConsistentMethod.invoke(reference, master);
        } catch (Exception e) {
            ThrowUnchecked.fireFirstDeclaredCause(e, FetchException.class);
            // Not reached.
            return false;
        }
    }
}