/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* 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 org.drools.core.meta;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.drools.core.common.ProjectClassLoader;
import org.drools.core.factmodel.traits.Entity;
import org.drools.core.meta.org.test.AnotherKlass;
import org.drools.core.meta.org.test.AnotherKlassImpl;
import org.drools.core.meta.org.test.AnotherKlass_;
import org.drools.core.meta.org.test.Klass;
import org.drools.core.meta.org.test.KlassImpl;
import org.drools.core.meta.org.test.Klass_;
import org.drools.core.meta.org.test.SubKlass;
import org.drools.core.meta.org.test.SubKlassImpl;
import org.drools.core.meta.org.test.SubKlass_;
import org.drools.core.metadata.Identifiable;
import org.drools.core.metadata.Lit;
import org.drools.core.metadata.MetadataContainer;
import org.drools.core.metadata.With;
import org.drools.core.test.model.Person;
import org.drools.core.util.StandaloneTraitFactory;
import org.junit.Test;
import static org.junit.Assert.*;
public class MetadataTest {
@Test
public void testKlassAndSubKlassWithImpl() {
SubKlass ski = new SubKlassImpl();
ski.setSubProp( 42 );
ski.setProp( "hello" );
SubKlass_ sk = new SubKlass_( ski );
assertEquals( 42, (int) sk.subProp.get( ski ) );
assertEquals( "hello", sk.prop.get( ski ) );
sk.modify().prop( "bye" ).subProp( -99 ).call();
assertEquals( -99, (int) sk.subProp.get( ski ) );
assertEquals( "bye", sk.prop.get( ski ) );
}
@Test
public void testKlassAndSubKlassWithHolderImpl() {
SubKlassImpl ski = new SubKlassImpl();
ski.setSubProp( 42 );
ski.setProp( "hello" );
SubKlass_ sk = ski.get_();
assertEquals( 42, (int) sk.subProp.get( ski ) );
assertEquals( "hello", sk.prop.get( ski ) );
sk.modify().prop( "bye" ).subProp( -99 ).call();
assertEquals( -99, (int) sk.subProp.get( ski ) );
assertEquals( "bye", sk.prop.get( ski ) );
}
@Test
public void testKlassAndSubKlassWithInterfaces() {
SubKlass ski = new Foo();
ski.setSubProp( 42 );
ski.setProp( "hello" );
SubKlass_ sk = new SubKlass_( ski );
assertEquals( 42, (int) sk.subProp.get( ski ) );
assertEquals( "hello", sk.prop.get( ski ) );
sk.modify().subProp( -99 ).prop( "bye" ).call();
assertEquals( -99, (int) sk.subProp.get( ski ) );
assertEquals( "bye", sk.prop.get( ski ) );
System.out.println( ((Foo) ski).map );
Map tgt = new HashMap();
tgt.put( "prop", "bye" );
tgt.put( "subProp", -99 );
assertEquals( tgt, ((Foo) ski).map );
}
@Test
public void testMetaPropertiesWithManyKlasses() {
SubKlass ski = new Foo();
ski.setSubProp( 42 );
ski.setProp( "hello" );
SubKlass_ sk = new SubKlass_( ski );
AnotherKlass aki = new AnotherKlassImpl();
aki.setNum( 1 );
AnotherKlass_ ak = new AnotherKlass_( aki );
sk.modify().subProp( -99 ).prop( "bye" ).call();
ak.modify().num( -5 ).call();
assertEquals( -5, aki.getNum() );
assertEquals( -99, (int) ski.getSubProp() );
}
@Test
public void testMetadataInternals() {
SubKlass_<SubKlass> sk = new SubKlass_( new SubKlassImpl() );
Klass_<Klass> k = new Klass_( new KlassImpl() );
AnotherKlass_<AnotherKlass> ak = new AnotherKlass_( new AnotherKlassImpl() );
assertEquals( 4, ak.getMetaClassInfo() .getProperties().length );
assertEquals( 4, sk.getMetaClassInfo() .getProperties().length );
assertEquals( 4, k.getMetaClassInfo().getProperties().length );
assertEquals( "subProp", sk.getMetaClassInfo().getProperties()[2].getName() );
}
@Test
public void testMetadataModifyStyle() {
SubKlassImpl ski = new SubKlassImpl();
SubKlass_.modify( ski ).prop( "hello" ).subProp( 42 ).call();
assertEquals( "hello", ski.getProp() );
assertEquals( 42, (int) ski.getSubProp() );
}
@Test
public void testModificationMask() {
SubKlassImpl ski = new SubKlassImpl();
SubKlass_.SubKlass_Modify task = SubKlass_.modify( ski ).prop( "hello" ).subProp( 42 );
task.call();
assertEquals( "144", task.getModificationMask().toString() );
SubKlass_.SubKlass_Modify task2 = SubKlass_.modify( ski ).prop( "hello" );
task2.call();
assertEquals( "16", task2.getModificationMask().toString() );
SubKlass_.SubKlass_Modify task3 = SubKlass_.modify( ski ).subProp( 42 );
task3.call();
assertEquals( "128", task3.getModificationMask().toString() );
}
@Test
public void testURIs() {
AnotherKlassImpl aki = new AnotherKlassImpl();
assertEquals( URI.create( "http://www.test.org#AnotherKlass" ), aki.get_().getMetaClassInfo().getUri() );
assertEquals( URI.create( "http://www.test.org#AnotherKlass?num" ), aki.get_().num.getUri() );
URI uri = AnotherKlass_.getIdentifier( aki );
assertEquals( URI.create( "http://www.test.org#AnotherKlass/AnotherKlassImpl/" +
System.identityHashCode( aki ) ),
uri );
assertEquals( URI.create( uri.toString() + "/modify?num" ),
AnotherKlass_.modify( aki ).num( 33 ).getUri() );
assertTrue( uri.toString().startsWith( aki.get_().getMetaClassInfo().getUri().toString() ) );
assertEquals( URI.create( "http://www.test.org#SubKlass/123?create" ),
SubKlass_.newSubKlass( URI.create( "http://www.test.org#SubKlass/123" ) ).getUri() );
assertEquals( URI.create( "123?don=org.drools.core.meta.org.test.AnotherKlass" ),
aki.get_().donAnotherKlass( new Foo() ).getUri() );
}
@Test
public void testNewInstance() {
Klass klass = Klass_.newKlass( URI.create( "test" ) ).call();
assertNotNull( klass );
assertTrue( klass instanceof KlassImpl );
SubKlass klass2 = SubKlass_.newSubKlass( URI.create( "test2" ) ).subProp( 42 ).prop( "hello" ).call();
assertEquals( "hello", klass2.getProp() );
assertEquals( 42, (int) klass2.getSubProp() );
}
@Test
public void testURIsOnLegacyClasses() {
Person p = new Person();
URI uri = MetadataContainer.getIdentifier( p );
assertEquals( URI.create( "urn:" + p.getClass().getPackage().getName() + "/" + p.getClass().getSimpleName() + "/" + System.identityHashCode( p ) ), uri );
}
@Test
public void testDon() {
Entity entity = new Entity( "123" );
entity._setDynamicProperties( new HashMap( ) );
entity._getDynamicProperties().put( "prop", "hello" );
Klass klass = Klass_.donKlass( entity )
.setTraitFactory( new StandaloneTraitFactory( ProjectClassLoader.createProjectClassLoader() ) )
.call();
assertEquals( "hello", klass.getProp() );
}
@Test
public void testDonWithAttributes() {
Entity entity = new Entity( "123" );
entity._setDynamicProperties( new HashMap() );
SubKlass klass = SubKlass_.donSubKlass( entity )
.setTraitFactory( new StandaloneTraitFactory( ProjectClassLoader.createProjectClassLoader() ) )
.prop( "hello" ).subProp( 32 )
.call();
assertEquals( "hello", klass.getProp() );
assertEquals( 32, (int) klass.getSubProp() );
}
@Test
public void testInitWithModifyArgs() {
AnotherKlass aki = AnotherKlass_.newAnotherKlass( "000" ).call();
SubKlass ski = SubKlass_.newSubKlass( URI.create( "123" ), With.with( aki ) ).prop( "hello" ).subProp( 42 ).another( aki ).call();
Klass ki = Klass_.newKlass( "1421" ).call();
assertEquals( "hello", ski.getProp() );
assertEquals( 42, (int) ski.getSubProp() );
assertEquals( aki, ski.getAnother() );
}
@Test
public void testCollectionOrientedProperties() {
AnotherKlass aki0 = AnotherKlass_.newAnotherKlass( "000" ).call();
AnotherKlass aki1 = AnotherKlass_.newAnotherKlass( "001" ).call();
AnotherKlass aki2 = AnotherKlass_.newAnotherKlass( "002" ).call();
AnotherKlass aki3 = AnotherKlass_.newAnotherKlass( "003" ).call();
AnotherKlass aki4 = AnotherKlass_.newAnotherKlass( "004" ).call();
ArrayList<AnotherKlass> initial = new ArrayList( Arrays.asList( aki0, aki1 ) );
SubKlass ski = SubKlass_.newSubKlass( URI.create( "123" ) )
.links( initial, Lit.SET )
.links( aki1, Lit.REMOVE )
.links( aki2, Lit.ADD )
.links( Arrays.asList( aki3, aki4 ), Lit.REMOVE )
.call();
assertEquals( Arrays.asList( aki0, aki2 ), ski.getLinks() );
}
@Test
public void testOneToOneProperty() {
AnotherKlass aki0 = AnotherKlass_.newAnotherKlass( "000" ).call();
Klass klass = Klass_.newKlass( "001" ).call();
Klass_.modify( klass, With.with( aki0 ) ).another( aki0 ).call();
assertSame( klass.getAnother(), aki0 );
assertSame( klass, aki0.getTheKlass() );
Klass klass1 = Klass_.newKlass( "002" ).call();
AnotherKlass_.modify( aki0 ).theKlass( klass1 ).call();
assertSame( aki0, klass1.getAnother() );
assertSame( klass1, aki0.getTheKlass() );
Klass_.modify( klass ).another( null ).call();
assertNull( klass.getAnother() );
assertNull( aki0.getTheKlass() );
}
@Test
public void testOneToManyProperty() {
AnotherKlass aki = AnotherKlass_.newAnotherKlass( "000" ).call();
AnotherKlass aki2 = AnotherKlass_.newAnotherKlass( "999" ).call();
Klass klass1 = Klass_.newKlass( "001" ).call();
Klass klass2 = Klass_.newKlass( "002" ).call();
AnotherKlass_.modify( aki, With.with( klass1, klass2 ) ).manyKlasses( new ArrayList( Arrays.asList( klass1, klass2 ) ), Lit.SET ).call();
assertSame( aki, klass1.getOneAnother() );
assertSame( aki, klass2.getOneAnother() );
AnotherKlass_.modify( aki2 ).manyKlasses( klass1, Lit.ADD ).call();
assertSame( aki2, klass1.getOneAnother() );
assertSame( aki, klass2.getOneAnother() );
assertFalse( aki.getManyKlasses().contains( klass1 ) );
assertTrue( aki2.getManyKlasses().contains( klass1 ) );
assertTrue( aki.getManyKlasses().contains( klass2 ) );
AnotherKlass_.modify( aki2 ).manyKlasses( klass1, Lit.REMOVE ).call();
assertNull( klass1.getOneAnother() );
assertFalse( aki2.getManyKlasses().contains( klass1 ) );
}
@Test
public void testManyToOneProperty() {
AnotherKlass aki = AnotherKlass_.newAnotherKlass( "000" ).call();
AnotherKlass aki2 = AnotherKlass_.newAnotherKlass( "999" ).call();
Klass klass1 = Klass_.newKlass( "001" ).call();
Klass klass2 = Klass_.newKlass( "002" ).call();
Klass_.modify( klass1 ).oneAnother( aki ).call();
Klass_.modify( klass2 ).oneAnother( aki ).call();
assertSame( aki, klass1.getOneAnother() );
assertSame( aki, klass2.getOneAnother() );
assertEquals( Arrays.asList( klass1, klass2 ), aki.getManyKlasses() );
Klass_.modify( klass1 ).oneAnother( aki2 ).call();
assertSame( aki2, klass1.getOneAnother() );
assertEquals( Arrays.asList( klass1 ), aki2.getManyKlasses() );
assertEquals( Arrays.asList( klass2 ), aki.getManyKlasses() );
}
@Test
public void testManyToManyProperty() {
AnotherKlass aki1 = AnotherKlass_.newAnotherKlass( "000" ).call();
AnotherKlass aki2 = AnotherKlass_.newAnotherKlass( "999" ).call();
Klass klass1 = Klass_.newKlass( "001" ).call();
Klass klass2 = Klass_.newKlass( "002" ).call();
Klass_.modify( klass1 ).manyOthers( aki1, Lit.ADD ).call();
Klass_.modify( klass1 ).manyOthers( aki2, Lit.ADD ).call();
AnotherKlass_.modify( aki2 ).manyMoreKlasses( klass2, Lit.ADD ).call();
AnotherKlass_.modify( aki1 ).manyMoreKlasses( klass2, Lit.ADD ).call();
assertTrue( klass1.getManyAnothers().contains( aki1 ) );
assertTrue( klass1.getManyAnothers().contains( aki2 ) );
assertTrue( klass2.getManyAnothers().contains( aki1 ) );
assertTrue( klass2.getManyAnothers().contains( aki2 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass2 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass2 ) );
AnotherKlass_.modify( aki2 ).manyMoreKlasses( klass2, Lit.REMOVE ).call();
assertTrue( klass1.getManyAnothers().contains( aki1 ) );
assertTrue( klass1.getManyAnothers().contains( aki2 ) );
assertTrue( klass2.getManyAnothers().contains( aki1 ) );
assertFalse( klass2.getManyAnothers().contains( aki2 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass2 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass1 ) );
assertFalse( aki2.getManyMoreKlasses().contains( klass2 ) );
AnotherKlass_.modify( aki2 ).manyMoreKlasses( klass2, Lit.ADD ).call();
assertTrue( klass1.getManyAnothers().contains( aki1 ) );
assertTrue( klass1.getManyAnothers().contains( aki2 ) );
assertTrue( klass2.getManyAnothers().contains( aki1 ) );
assertTrue( klass2.getManyAnothers().contains( aki2 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass2 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass2 ) );
AnotherKlass_.modify( aki2 ).manyMoreKlasses( klass2, Lit.SET ).call();
assertTrue( klass1.getManyAnothers().contains( aki1 ) );
assertFalse( klass1.getManyAnothers().contains( aki2 ) );
assertTrue( klass2.getManyAnothers().contains( aki1 ) );
assertTrue( klass2.getManyAnothers().contains( aki2 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki1.getManyMoreKlasses().contains( klass2 ) );
assertFalse( aki2.getManyMoreKlasses().contains( klass1 ) );
assertTrue( aki2.getManyMoreKlasses().contains( klass2 ) );
}
public static class Foo implements SubKlass, Identifiable {
private URI uri;
public Foo() {
this( "123" );
}
public Foo( String uri ) {
this.uri = URI.create( uri );
}
public Map<String,Object> map = new HashMap<String,Object>();
@Override
public String getProp() {
return (String) map.get( "prop" );
}
@Override
public void setProp( String value ) {
map.put( "prop", value );
}
@Override
public AnotherKlass getAnother() {
return (AnotherKlass) map.get( "another" );
}
@Override
public void setAnother( AnotherKlass another ) {
map.put( "another", another );
}
@Override
public AnotherKlass getOneAnother() {
return null;
}
@Override
public void setOneAnother( AnotherKlass another ) {
}
@Override
public List<AnotherKlass> getManyAnothers() {
return null;
}
@Override
public void setManyAnothers( List<AnotherKlass> anothers ) {
}
@Override
public Integer getSubProp() {
return (Integer) map.get( "subProp" );
}
@Override
public void setSubProp( Integer value ) {
map.put( "subProp", value );
}
@Override
public List<AnotherKlass> getLinks() {
return null;
}
@Override
public void setLinks( List<AnotherKlass> links ) {
}
@Override
public URI getUri() {
return uri;
}
@Override
public Object getId() {
return uri;
}
}
}