Package org.apache.cayenne.map

Source Code of org.apache.cayenne.map.ObjRelationshipTest

/*****************************************************************
*   Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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 org.apache.cayenne.map;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.Collections;
import java.util.List;

import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.configuration.DataMapLoader;
import org.apache.cayenne.configuration.server.ServerRuntime;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.ExpressionException;
import org.apache.cayenne.resource.URLResource;
import org.apache.cayenne.testdo.inheritance.vertical.Iv2Sub1;
import org.apache.cayenne.unit.di.server.ServerCase;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.util.XMLEncoder;

@UseServerRuntime(ServerCase.TESTMAP_PROJECT)
public class ObjRelationshipTest extends ServerCase {

  @Inject
  private ServerRuntime runtime;

  private DbEntity artistDBEntity;
  private DbEntity artistExhibitDBEntity;
  private DbEntity exhibitDBEntity;
  private DbEntity paintingDbEntity;
  private DbEntity galleryDBEntity;

  @Override
  protected void setUpAfterInjection() throws Exception {
    EntityResolver resolver = runtime.getDataDomain().getEntityResolver();

    artistDBEntity = resolver.getDbEntity("ARTIST");
    artistExhibitDBEntity = resolver.getDbEntity("ARTIST_EXHIBIT");
    exhibitDBEntity = resolver.getDbEntity("EXHIBIT");
    paintingDbEntity = resolver.getDbEntity("PAINTING");
    galleryDBEntity = resolver.getDbEntity("GALLERY");
  }

  public void testEncodeAsXML() {
    StringWriter buffer = new StringWriter();
    PrintWriter out = new PrintWriter(buffer);
    XMLEncoder encoder = new XMLEncoder(out);

    DataMap map = new DataMap("M");
    ObjEntity source = new ObjEntity("S");
    ObjEntity target = new ObjEntity("T");
    map.addObjEntity(source);
    map.addObjEntity(target);

    ObjRelationship r = new ObjRelationship("X");
    r.setSourceEntity(source);
    r.setTargetEntityName("T");
    r.setCollectionType("java.util.Map");
    r.setMapKey("bla");

    r.encodeAsXML(encoder);
    out.close();

    String lineBreak = System.getProperty("line.separator");

    assertEquals("<obj-relationship name=\"X\" source=\"S\" target=\"T\" "
        + "collection-type=\"java.util.Map\" map-key=\"bla\"/>"
        + lineBreak, buffer.getBuffer().toString());
  }

  public void testCollectionType() {
    ObjRelationship r = new ObjRelationship("X");
    assertNull(r.getCollectionType());
    r.setCollectionType("java.util.Map");
    assertEquals("java.util.Map", r.getCollectionType());
  }

  public void testSerializability() throws Exception {
    ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");

    // start with "to many"
    ObjRelationship r1 = (ObjRelationship) artistObjEnt
        .getRelationship("paintingArray");

    ObjRelationship r2 = Util.cloneViaSerialization(r1);
    assertEquals(r1.getName(), r2.getName());
    assertEquals(r1.getDbRelationshipPath(), r2.getDbRelationshipPath());
  }

  public void testGetClientRelationship() {
    final ObjEntity target = new ObjEntity("te1");
    ObjRelationship r1 = new ObjRelationship("r1") {

      @Override
      public Entity getTargetEntity() {
        return target;
      }
    };

    r1.setDeleteRule(DeleteRule.DENY);
    r1.setTargetEntityName("te1");

    ObjRelationship r2 = r1.getClientRelationship();
    assertNotNull(r2);
    assertEquals(r1.getName(), r2.getName());
    assertEquals(r1.getTargetEntityName(), r2.getTargetEntityName());
    assertEquals(r1.getDeleteRule(), r2.getDeleteRule());
  }

  public void testGetReverseDbRelationshipPath() {
    ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");
    ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Painting");

    // start with "to many"
    ObjRelationship r1 = (ObjRelationship) artistObjEnt
        .getRelationship("paintingArray");

    assertEquals("toArtist", r1.getReverseDbRelationshipPath());

    ObjRelationship r2 = (ObjRelationship) paintingObjEnt
        .getRelationship("toArtist");

    assertEquals("paintingArray", r2.getReverseDbRelationshipPath());
  }

  public void testSetDbRelationshipPath() {
    ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");

    ObjRelationship r = new ObjRelationship("r");
    r.setSourceEntity(artistObjEnt);
    r.setDbRelationshipPath("paintingArray");
    assertEquals(r.getDbRelationshipPath(), "paintingArray");
  }

  public void testRefreshFromPath() {
    ObjRelationship relationship = new ObjRelationship();

    // attempt to resolve must fail - relationship is outside of context,
    // plus the path is random
    try {
      relationship.setDbRelationshipPath("dummy.path");
      fail("set random path should have failed.");
    } catch (CayenneRuntimeException ex) {
      // expected
    }

    DataMap map = new DataMap();
    ObjEntity entity = new ObjEntity("Test");
    map.addObjEntity(entity);

    relationship.setSourceEntity(entity);
    // attempt to resolve must fail - relationship is outside of context,
    // plus the path is random
    try {
      relationship.refreshFromPath("dummy.path", false);
      fail("refresh over a dummy path should have failed.");
    } catch (ExpressionException ex) {
      // expected
    }

    // finally assemble ObjEntity to make the path valid
    DbEntity dbEntity1 = new DbEntity("TEST1");
    DbEntity dbEntity2 = new DbEntity("TEST2");
    DbEntity dbEntity3 = new DbEntity("TEST3");
    map.addDbEntity(dbEntity1);
    map.addDbEntity(dbEntity2);
    map.addDbEntity(dbEntity3);
    entity.setDbEntityName("TEST1");
    DbRelationship dummyR = new DbRelationship("dummy");
    dummyR.setTargetEntityName("TEST2");
    dummyR.setSourceEntity(dbEntity1);
    DbRelationship pathR = new DbRelationship("path");
    pathR.setTargetEntityName("TEST3");
    pathR.setSourceEntity(dbEntity2);
    dbEntity1.addRelationship(dummyR);
    dbEntity2.addRelationship(pathR);

    relationship.refreshFromPath("dummy.path", false);

    List<DbRelationship> resolvedPath = relationship.getDbRelationships();
    assertEquals(2, resolvedPath.size());
    assertSame(dummyR, resolvedPath.get(0));
    assertSame(pathR, resolvedPath.get(1));
  }

  public void testCalculateToMany() {
    // assemble fixture....
    DataMap map = new DataMap();
    ObjEntity entity = new ObjEntity("Test");
    map.addObjEntity(entity);

    DbEntity dbEntity1 = new DbEntity("TEST1");
    DbEntity dbEntity2 = new DbEntity("TEST2");
    DbEntity dbEntity3 = new DbEntity("TEST3");
    map.addDbEntity(dbEntity1);
    map.addDbEntity(dbEntity2);
    map.addDbEntity(dbEntity3);
    entity.setDbEntityName("TEST1");
    DbRelationship dummyR = new DbRelationship("dummy");
    dummyR.setTargetEntityName("TEST2");
    dummyR.setSourceEntity(dbEntity1);
    DbRelationship pathR = new DbRelationship("path");
    pathR.setTargetEntityName("TEST3");
    pathR.setSourceEntity(dbEntity2);
    dbEntity1.addRelationship(dummyR);
    dbEntity2.addRelationship(pathR);

    ObjRelationship relationship = new ObjRelationship();
    relationship.setSourceEntity(entity);

    // test how toMany changes dependending on the underlying
    // DbRelationships
    // add DbRelationships directly to avoid events to test
    // "calculateToMany"
    relationship.dbRelationships.add(dummyR);
    assertFalse(relationship.isToMany());

    dummyR.setToMany(true);
    relationship.recalculateToManyValue();
    assertTrue(relationship.isToMany());

    dummyR.setToMany(false);
    relationship.recalculateToManyValue();
    assertFalse(relationship.isToMany());

    // test chain
    relationship.dbRelationships.add(pathR);
    assertFalse(relationship.isToMany());

    pathR.setToMany(true);
    relationship.recalculateToManyValue();
    assertTrue(relationship.isToMany());
  }

  public void testCalculateToManyFromPath() {
    // assemble fixture....
    DataMap map = new DataMap();
    ObjEntity entity = new ObjEntity("Test");
    map.addObjEntity(entity);

    DbEntity dbEntity1 = new DbEntity("TEST1");
    DbEntity dbEntity2 = new DbEntity("TEST2");
    DbEntity dbEntity3 = new DbEntity("TEST3");
    map.addDbEntity(dbEntity1);
    map.addDbEntity(dbEntity2);
    map.addDbEntity(dbEntity3);
    entity.setDbEntityName("TEST1");
    DbRelationship dummyR = new DbRelationship("dummy");
    dummyR.setTargetEntityName("TEST2");
    dummyR.setSourceEntity(dbEntity1);
    DbRelationship pathR = new DbRelationship("path");
    pathR.setTargetEntityName("TEST3");
    pathR.setSourceEntity(dbEntity2);
    dbEntity1.addRelationship(dummyR);
    dbEntity2.addRelationship(pathR);

    ObjRelationship relationship = new ObjRelationship();
    relationship.setSourceEntity(entity);

    // test how toMany changes when the path is set as a string

    relationship.setDbRelationshipPath("dummy");
    assertFalse(relationship.isToMany());

    dummyR.setToMany(true);
    relationship.setDbRelationshipPath(null);
    relationship.setDbRelationshipPath("dummy");
    assertTrue(relationship.isToMany());

    dummyR.setToMany(false);
    relationship.setDbRelationshipPath(null);
    relationship.setDbRelationshipPath("dummy");
    assertFalse(relationship.isToMany());

    // test chain
    relationship.setDbRelationshipPath(null);
    relationship.setDbRelationshipPath("dummy.path");
    assertFalse(relationship.isToMany());

    pathR.setToMany(true);
    relationship.setDbRelationshipPath(null);
    relationship.setDbRelationshipPath("dummy.path");
    assertTrue(relationship.isToMany());
  }

  public void testTargetEntity() throws Exception {
    ObjRelationship relationship = new ObjRelationship("some_rel");
    relationship.setTargetEntityName("targ");

    try {
      relationship.getTargetEntity();
      fail("Without a container, getTargetEntity() must fail.");
    } catch (CayenneRuntimeException ex) {
      // expected
    }

    // assemble container
    DataMap map = new DataMap();
    ObjEntity src = new ObjEntity("src");
    map.addObjEntity(src);

    src.addRelationship(relationship);
    assertNull(relationship.getTargetEntity());

    ObjEntity target = new ObjEntity("targ");
    map.addObjEntity(target);

    assertSame(target, relationship.getTargetEntity());
  }

  public void testGetReverseRel1() {

    ObjEntity artistObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");
    ObjEntity paintingObjEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Painting");

    // start with "to many"
    ObjRelationship r1 = (ObjRelationship) artistObjEnt
        .getRelationship("paintingArray");
    ObjRelationship r2 = r1.getReverseRelationship();

    assertNotNull(r2);
    assertSame(paintingObjEnt.getRelationship("toArtist"), r2);
  }

  public void testGetReverseRel2() {
    ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");
    ObjEntity paintingEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Painting");

    // start with "to one"
    ObjRelationship r1 = (ObjRelationship) paintingEnt
        .getRelationship("toArtist");
    ObjRelationship r2 = r1.getReverseRelationship();

    assertNotNull(r2);
    assertSame(artistEnt.getRelationship("paintingArray"), r2);
  }

  public void testSingleDbRelationship() {
    ObjRelationship relationship = new ObjRelationship();
    DbRelationship r1 = new DbRelationship("X");
    relationship.addDbRelationship(r1);
    assertEquals(1, relationship.getDbRelationships().size());
    assertEquals(r1, relationship.getDbRelationships().get(0));
    assertFalse(relationship.isFlattened());
    assertFalse(relationship.isReadOnly());
    assertEquals(r1.isToMany(), relationship.isToMany());
    relationship.removeDbRelationship(r1);
    assertEquals(0, relationship.getDbRelationships().size());
  }

  public void testFlattenedRelationship() {
    DbRelationship r1 = new DbRelationship("X");
    DbRelationship r2 = new DbRelationship("Y");

    r1.setSourceEntity(artistDBEntity);
    r1.setTargetEntity(artistExhibitDBEntity);
    r1.setToMany(true);

    r2.setSourceEntity(artistExhibitDBEntity);
    r2.setTargetEntity(exhibitDBEntity);
    r2.setToMany(false);

    ObjRelationship relationship = new ObjRelationship();
    relationship.addDbRelationship(r1);
    relationship.addDbRelationship(r2);
    assertTrue(relationship.isToMany());
    assertEquals(2, relationship.getDbRelationships().size());
    assertEquals(r1, relationship.getDbRelationships().get(0));
    assertEquals(r2, relationship.getDbRelationships().get(1));

    assertTrue(relationship.isFlattened());

    relationship.removeDbRelationship(r1);
    assertFalse(relationship.isToMany()); // only remaining rel is r2... a
                        // toOne
    assertEquals(1, relationship.getDbRelationships().size());
    assertEquals(r2, relationship.getDbRelationships().get(0));
    assertFalse(relationship.isFlattened());
    assertFalse(relationship.isReadOnly());

  }

  public void testReadOnly_Flattened1_1__N_1() {

    // check common vertical inheritance relationships

    DataMapLoader loader = runtime.getInjector().getInstance(
        DataMapLoader.class);
    URL url = getClass().getClassLoader().getResource(
        "inheritance-vertical.map.xml");
    DataMap dataMap = loader.load(new URLResource(url));
    EntityResolver resolver = new EntityResolver(
        Collections.singleton(dataMap));

    ObjEntity iv2Sub1 = resolver.getObjEntity(Iv2Sub1.class);
    ObjRelationship x = (ObjRelationship) iv2Sub1
        .getRelationship(Iv2Sub1.X_PROPERTY);
    assertTrue(x.isFlattened());
    assertFalse(x.isReadOnly());
  }

  public void testReadOnlyMoreThan3DbRelsRelationship() {
    // Readonly is a flattened relationship that isn't over a single
    // many->many link
    // table
    DbRelationship r1 = new DbRelationship("X");
    DbRelationship r2 = new DbRelationship("Y");
    DbRelationship r3 = new DbRelationship("Z");

    r1.setSourceEntity(artistDBEntity);
    r1.setTargetEntity(artistExhibitDBEntity);
    r1.setToMany(true);
    r2.setSourceEntity(artistExhibitDBEntity);
    r2.setTargetEntity(exhibitDBEntity);
    r2.setToMany(false);
    r3.setSourceEntity(exhibitDBEntity);
    r3.setTargetEntity(galleryDBEntity);
    r3.setToMany(false);

    ObjRelationship relationship = new ObjRelationship();
    relationship.addDbRelationship(r1);
    relationship.addDbRelationship(r2);
    relationship.addDbRelationship(r3);

    assertTrue(relationship.isFlattened());
    assertTrue(relationship.isReadOnly());
    assertTrue(relationship.isToMany());

  }

  // Test for a read-only flattened relationship that is readonly because it's
  // dbrel
  // sequence is "incorrect" (or rather, unsupported)
  public void testIncorrectSequenceReadOnlyRelationship() {
    DbRelationship r1 = new DbRelationship("X");
    DbRelationship r2 = new DbRelationship("Y");

    r1.setSourceEntity(artistDBEntity);
    r1.setTargetEntity(paintingDbEntity);
    r1.setToMany(true);
    r2.setSourceEntity(paintingDbEntity);
    r2.setTargetEntity(galleryDBEntity);
    r2.setToMany(false);

    ObjRelationship relationship = new ObjRelationship();
    relationship.addDbRelationship(r1);
    relationship.addDbRelationship(r2);

    assertTrue(relationship.isFlattened());
    assertTrue(relationship.isReadOnly());
    assertTrue(relationship.isToMany());
  }

  // Test a relationship loaded from the test datamap that we know should be
  // flattened
  public void testKnownFlattenedRelationship() {
    ObjEntity artistEnt = runtime.getDataDomain().getEntityResolver()
        .getObjEntity("Artist");
    ObjRelationship theRel = (ObjRelationship) artistEnt
        .getRelationship("groupArray");
    assertNotNull(theRel);
    assertTrue(theRel.isFlattened());
    assertFalse(theRel.isReadOnly());
  }

  public void testBadDeleteRuleValue() {
    ObjRelationship relationship = new ObjRelationship();

    try {
      relationship.setDeleteRule(999);
      fail("Should have failed with IllegalArgumentException");
    } catch (IllegalArgumentException e) {
      // Good... it should throw an exception
    }
  }

  public void testOkDeleteRuleValue() {
    ObjRelationship relationship = new ObjRelationship();
    try {
      relationship.setDeleteRule(DeleteRule.CASCADE);
      relationship.setDeleteRule(DeleteRule.DENY);
      relationship.setDeleteRule(DeleteRule.NULLIFY);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      fail("Should not have thrown an exception :" + e.getMessage());
    }
  }
}
TOP

Related Classes of org.apache.cayenne.map.ObjRelationshipTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.