package org.jboss.tools.hibernate.runtime.v_5_2.internal;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import org.hibernate.HibernateException;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.ShortType;
import org.hibernate.type.Type;
import org.jboss.tools.hibernate.runtime.common.AbstractClassMetadataFacade;
import org.jboss.tools.hibernate.runtime.common.IFacade;
import org.jboss.tools.hibernate.runtime.common.IFacadeFactory;
import org.jboss.tools.hibernate.runtime.spi.IClassMetadata;
import org.jboss.tools.hibernate.runtime.spi.ISession;
import org.jboss.tools.hibernate.runtime.spi.IType;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ClassMetadataFacadeTest {
private static final IFacadeFactory FACADE_FACTORY = new FacadeFactoryImpl();
private String methodName = null;
private Object[] arguments = null;
private IClassMetadata classMetadata = null;
private boolean hasIdentifierProperty = false;
@Before
public void setUp() {
ClassMetadata target = (ClassMetadata)Proxy.newProxyInstance(
FACADE_FACTORY.getClassLoader(),
new Class[] { ClassMetadata.class },
new TestInvocationHandler());
classMetadata = new ClassMetadataFacadeImpl(FACADE_FACTORY, target);
}
@Test
public void testGetMappedClass() {
Assert.assertNull(classMetadata.getMappedClass());
Assert.assertEquals("getMappedClass", methodName);
Assert.assertNull(arguments);
}
@Test
public void testGetPropertyValue() {
Object object = new Object();
String name = "foobar";
Assert.assertNull(classMetadata.getPropertyValue(object, name));
Assert.assertEquals("getPropertyValue", methodName);
Assert.assertArrayEquals(new Object[] { object, name }, arguments);
}
@Test
public void testGetIdentifierPropertyName() {
Assert.assertNull(classMetadata.getIdentifierPropertyName());
Assert.assertEquals("getIdentifierPropertyName", methodName);
Assert.assertNull(arguments);
}
@Test
public void testGetEntityName() {
Assert.assertNull(classMetadata.getEntityName());
Assert.assertEquals("getEntityName", methodName);
Assert.assertNull(arguments);
}
@Test
public void testGetPropertyNames() {
Assert.assertNull(classMetadata.getPropertyNames());
Assert.assertEquals("getPropertyNames", methodName);
Assert.assertNull(arguments);
}
@Test
public void testGetPropertyTypes() {
IType[] propertyTypes = classMetadata.getPropertyTypes();
Assert.assertEquals(1, propertyTypes.length);
Assert.assertEquals("getPropertyTypes", methodName);
Assert.assertNull(arguments);
methodName = null;
Assert.assertSame(propertyTypes, classMetadata.getPropertyTypes());
Assert.assertNull(methodName);
Assert.assertNull(arguments);
}
@Test
public void testGetIdentifierType() {
IType identifierType = classMetadata.getIdentifierType();
Assert.assertNotNull(identifierType);
Assert.assertEquals("getIdentifierType", methodName);
Assert.assertNull(arguments);
methodName = null;
Assert.assertSame(identifierType, classMetadata.getIdentifierType());
Assert.assertNull(methodName);
Assert.assertNull(arguments);
}
@Test
public void testIsInstanceOfAbstractEntityPersister() {
Assert.assertFalse(classMetadata.isInstanceOfAbstractEntityPersister());
classMetadata = new AbstractClassMetadataFacade(FACADE_FACTORY, createSampleEntityPersister()) {};
Assert.assertTrue(classMetadata.isInstanceOfAbstractEntityPersister());
}
@Test
public void testGetEntityMetaModel() {
Assert.assertNull(classMetadata.getEntityMetamodel());
Assert.assertNull(methodName);
TestEntityPersister entityPersister = createSampleEntityPersister();
classMetadata = new AbstractClassMetadataFacade(FACADE_FACTORY, entityPersister) {};
methodName = null;
Assert.assertNotNull(classMetadata.getEntityMetamodel());
Assert.assertEquals("getEntityMetamodel", methodName);
}
@Test
public void testGetIdentifier() {
ClassLoader cl = FACADE_FACTORY.getClassLoader();
final SessionImplementor sessionTarget = (SessionImplementor)Proxy.newProxyInstance(
cl,
new Class[] { SessionImplementor.class },
new TestInvocationHandler());
ISession session = (ISession)Proxy.newProxyInstance(
cl,
new Class[] { ISession.class, IFacade.class },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return sessionTarget;
}
});
Object object = Integer.MAX_VALUE;
Assert.assertSame(object, classMetadata.getIdentifier(object , session));
Assert.assertEquals("getIdentifier", methodName);
Assert.assertArrayEquals(new Object[] { object, sessionTarget }, arguments);
}
public void testHasIdentifierProperty() {
hasIdentifierProperty = true;
Assert.assertTrue(classMetadata.hasIdentifierProperty());
hasIdentifierProperty = false;
Assert.assertFalse(hasIdentifierProperty);
Assert.assertEquals("hasIdentifierProperty", methodName);
Assert.assertNull(arguments);
}
private TestEntityPersister createSampleEntityPersister() {
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
builder.applySetting("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
ServiceRegistry serviceRegistry = builder.build();
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
MetadataImplementor metadata = (MetadataImplementor)metadataSources.buildMetadata();
SessionFactoryImplementor sfi = (SessionFactoryImplementor)metadata.buildSessionFactory();
RootClass rc = new RootClass(null);
Table t = new Table("foobar");
rc.setTable(t);
Column c = new Column("foo");
t.addColumn(c);
ArrayList<Column> keyList = new ArrayList<>();
keyList.add(c);
t.createUniqueKey(keyList);
SimpleValue sv = new SimpleValue(metadata);
sv.setNullValue("null");
sv.setTypeName(Integer.class.getName());
sv.addColumn(c);
rc.setEntityName("foobar");
rc.setIdentifier(sv);
return new TestEntityPersister(rc, sfi, metadata);
}
private class TestPersisterCreationContext implements PersisterCreationContext {
final private SessionFactoryImplementor sfi;
final private MetadataImplementor md;
private TestPersisterCreationContext(
SessionFactoryImplementor sfi,
MetadataImplementor md) {
this.sfi = sfi;
this.md = md;
}
@Override
public SessionFactoryImplementor getSessionFactory() {
return sfi;
}
@Override
public MetadataImplementor getMetadata() {
return md;
}
}
private class TestEntityPersister extends SingleTableEntityPersister {
public TestEntityPersister(
PersistentClass pc,
SessionFactoryImplementor sfi,
MetadataImplementor md) throws HibernateException {
super(pc, null, null, new TestPersisterCreationContext(sfi, md));
}
@Override public EntityMetamodel getEntityMetamodel() {
methodName = "getEntityMetamodel";
return super.getEntityMetamodel();
}
}
private class TestInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
methodName = method.getName();
arguments = args;
if ("getPropertyTypes".equals(methodName)) {
return new Type[] { new ShortType() };
} else if ("getIdentifierType".equals(methodName)) {
return new ShortType();
} else if ("getIdentifier".equals(methodName)) {
return args[0];
} else if ("hasIdentifierProperty".equals(methodName)) {
return hasIdentifierProperty;
} else {
return null;
}
}
}
}