/*
* 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;
}
}
}