gt:     DimensionMetaData custGeoDim = dims.get(0);
context: /*!
  * This program is free software; you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
  * Foundation.
  *
  * You should have received a copy of the GNU Lesser General Public License along with this
  * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
  * or from the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU Lesser General Public License for more details.
  *
  * Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
  */
  
  package org.pentaho.agilebi.modeler.geo;
  
  import org.junit.BeforeClass;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.pentaho.agilebi.modeler.AbstractModelerTest;
  import org.pentaho.agilebi.modeler.ModelerPerspective;
  import org.pentaho.agilebi.modeler.nodes.*;
  import org.pentaho.agilebi.modeler.nodes.annotations.IDataRoleAnnotation;
  import org.pentaho.agilebi.modeler.nodes.annotations.IMemberAnnotation;
  import org.pentaho.metadata.model.IPhysicalColumn;
  import org.pentaho.metadata.model.IPhysicalTable;
  import org.pentaho.metadata.model.LogicalColumn;
  import org.pentaho.metadata.model.concept.types.DataType;
  import org.pentaho.metadata.model.olap.OlapDimension;
  import org.pentaho.metadata.model.olap.OlapHierarchy;
  import org.pentaho.metadata.model.olap.OlapHierarchyLevel;
  
  import java.io.File;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.Reader;
  import java.util.*;
  
  import static org.easymock.EasyMock.*;
  import static org.junit.Assert.*;
  
  /**
   * Created by IntelliJ IDEA.
   * User: rfellows
   * Date: 9/16/11
   * Time: 9:19 AM
   * To change this template use File | Settings | File Templates.
   */
  public class GeoContextTest extends AbstractModelerTest {
    private static final String GEO_ROLE_KEY = "geo.roles";
    private static Properties props = null;
    private static final String LOCALE = "en_US";
  
    private static GeoContextConfigProvider config;
  
    @BeforeClass
    public static void bootstrap() throws IOException {
      Reader propsReader = new FileReader(new File("test-res/geoRoles.properties"));
      props = new Properties();
      props.load(propsReader);
      config = new GeoContextPropertiesProvider(props);
    }
  
    @Test
    public void addGeoRole() {
      GeoContext geo = new GeoContext();
      assertEquals(0, geo.size());
      geo.addGeoRole(new GeoRole("country", Arrays.asList(new String[]{"country, ctry"})));
      geo.addGeoRole(new GeoRole("state", Arrays.asList(new String[]{"state, st, province"})));
      geo.addGeoRole(new GeoRole("city", Arrays.asList(new String[]{"city, town"})));
      assertEquals(3, geo.size());
  
      // make sure they are in the same order as entered
      assertEquals("country", geo.getGeoRole(0).getName());
      assertEquals("state", geo.getGeoRole(1).getName());
      assertEquals("city", geo.getGeoRole(2).getName());
    }
  
    @Test
    public void testMatchingAliasesToRole() throws Exception {
  
      // pre-configure to use the CUSTOMERS table
      generateTestDomain();
      
      GeoContext geo = GeoContextFactory.create(config);
      List<GeoRole> matched = new ArrayList<GeoRole>();
  
      List<AvailableTable> tables = workspace.getAvailableTables().getAsAvailableTablesList();
  
      // CUSTOMERS table has CITY, COUNTRY, STATE, and POSTALCODE fields that should be auto-detected
      for(AvailableTable t: tables){
        for(AvailableField field: t.getAvailableFields()) {
          GeoRole geoRole = geo.matchFieldToGeoRole(field);
          if (geoRole != null) {
            matched.add(geoRole);
            System.out.println("Identified geo field " + field.getName() + " => " + geoRole.getName());
          }
        }
      }
    }
  
    @Test
    public void testMatchingAliasToRole_prefixedPhysicalColumn() throws Exception {
  
      GeoContext geo = GeoContextFactory.create(config);
  
      IPhysicalColumn mockStateCol = createMock(IPhysicalColumn.class);
      expect(mockStateCol.getId()).andReturn("pc__STATE").anyTimes();
      expect(mockStateCol.getName(LOCALE)).andReturn("State").anyTimes();
      expect(mockStateCol.getName("en-US")).andReturn("State").anyTimes();
  
      IPhysicalColumn mockLatCol = createMock(IPhysicalColumn.class);
      expect(mockLatCol.getId()).andReturn("pc__CUSTOMER_LATITUDE").anyTimes();
      expect(mockLatCol.getName(LOCALE)).andReturn("Customer_Latitude").anyTimes();
      expect(mockLatCol.getName("en-US")).andReturn("Customer_Latitude").anyTimes();
  
      replay(mockStateCol);
      replay(mockLatCol);
  
      AvailableField field = new AvailableField(mockStateCol);
  
      GeoRole geoRole = geo.matchFieldToGeoRole(field);
      assertNotNull(geoRole);
      assertEquals("state", geoRole.getName());
  
      field = new AvailableField(mockLatCol);
  
      geoRole = geo.matchFieldToGeoRole(field);
      assertNotNull(geoRole);
      assertEquals("location", geoRole.getName());
  
    }
  
    @Test
    public void testBuildingGeoDimensions() throws Exception {
      // pre-configure to use the CUSTOMERS table
      generateTestDomain();
  
      GeoContext geo = GeoContextFactory.create(config);
      List<DimensionMetaData> geoDims = geo.buildDimensions(workspace);
      assertNotNull(geoDims);
      assertEquals(1, geoDims.size());
  
      DimensionMetaData dim = geoDims.get(0);
      assertNotNull(dim);
  
  
      IDataRoleAnnotation dataRole =  (IDataRoleAnnotation) dim.getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
      assertTrue(dataRole instanceof GeoRole);
  
      dataRole =  (IDataRoleAnnotation) dim.get(0).getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
      assertTrue(dataRole instanceof GeoRole);
  
      // CUSTOMERS table has CITY, COUNTRY, STATE, and POSTALCODE fields that should be auto-detected
      assertEquals(4, dim.get(0).size());
  
      int lastFoundIndex = 0;
      int found = 0;
      // make sure they are in the correct order
      for (int i = 0; i < dim.get(0).size(); i++) {
        LevelMetaData level = dim.get(0).get(i);
  
        dataRole =  (IDataRoleAnnotation) level.getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
        assertTrue(dataRole instanceof GeoRole);
  
        for(int j = lastFoundIndex; j < geo.size(); j++) {
          GeoRole role = geo.getGeoRole(j);
          GeoRole geoRole =  (GeoRole) level.getMemberAnnotations().get(GeoContext.ANNOTATION_GEO_ROLE);
  
          if(geoRole.equals(role)) {
            assertTrue(i <= lastFoundIndex);
            lastFoundIndex = j;
            found++;
            continue;
          }
        }
      }
      assertTrue(found == dim.get(0).size());
    }
  
  
    @Test
    public void testBuildingGeoDimension_MultiTable() throws Exception {
      generateMultiStarTestDomain();
  
      GeoContext geo = GeoContextFactory.create(config);
      List<DimensionMetaData> geoDims = geo.buildDimensions(workspace);
      assertNotNull(geoDims);
      assertEquals(1, geoDims.size());
  
      DimensionMetaData dim = geoDims.get(0);
      assertNotNull(dim);
  
  
      IDataRoleAnnotation dataRole =  (IDataRoleAnnotation) dim.getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
  
      assertTrue(dataRole instanceof GeoRole);
      dataRole =  (IDataRoleAnnotation) dim.get(0).getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
      assertTrue(dataRole instanceof GeoRole);
  
      // CUSTOMERS table has CITY, COUNTRY, STATE, and POSTALCODE fields that should be auto-detected
      assertEquals(4, dim.get(0).size());
  
      int lastFoundIndex = 0;
      int found = 0;
      // make sure they are in the correct order
      for (int i = 0; i < dim.get(0).size(); i++) {
        LevelMetaData level = dim.get(0).get(i);
        dataRole =  (IDataRoleAnnotation) dim.get(0).getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE);
        assertTrue(dataRole instanceof GeoRole);
        for(int j = lastFoundIndex; j < geo.size(); j++) {
          DataRole role = geo.getGeoRole(j);
          if(level.getMemberAnnotations().get(GeoContext.ANNOTATION_DATA_ROLE).equals(role)) {
            assertTrue(i <= lastFoundIndex);
            lastFoundIndex = j;
            found++;
            continue;
          }
        }
      }
      assertTrue(found == dim.get(0).size());
    }
  
    @Test
    public void testMultipleTablesWithGeoFields() throws Exception {
  
      // build up 2 mock tables that both have geographic fields, make sure that
      // 2 dimensions are built, one for each table.
  
      List<IAvailableItem> items = new ArrayList<IAvailableItem>();
  
      // mock object init...
      IPhysicalTable mockTable1 = createMock(IPhysicalTable.class);
      List<IPhysicalColumn> cols1 = new ArrayList<IPhysicalColumn>();
      IPhysicalColumn mockStateCol = createMock(IPhysicalColumn.class);
      cols1.add(mockStateCol);
  
      expect(mockTable1.getName(LOCALE)).andReturn("CUSTOMERS").anyTimes();
      expect(mockTable1.getPhysicalColumns()).andReturn(cols1).anyTimes();
      expect(mockTable1.getId()).andReturn("PT_CUSTOMERS").anyTimes();
      expect(mockTable1.getProperty("target_table")).andReturn("PT_CUSTOMERS").anyTimes();
  
      expect(mockStateCol.getName(LOCALE)).andReturn("State").anyTimes();
      expect(mockStateCol.getName("en-US")).andReturn("State").anyTimes();
      expect(mockStateCol.getPhysicalTable()).andReturn(mockTable1).anyTimes();
      expect(mockStateCol.getDataType()).andReturn(DataType.STRING);
      expect(mockStateCol.getAggregationList()).andReturn(null);
      expect(mockStateCol.getAggregationType()).andReturn(null);
      expect(mockStateCol.getId()).andReturn("STATE").anyTimes();
  
      IPhysicalTable mockTable2 = createMock(IPhysicalTable.class);
      List<IPhysicalColumn> cols2 = new ArrayList<IPhysicalColumn>();
      IPhysicalColumn mockCountryCol = createMock(IPhysicalColumn.class);
      cols2.add(mockCountryCol);
      IPhysicalColumn mockStateCol2 = createMock(IPhysicalColumn.class);
      cols2.add(mockStateCol2);
  
      expect(mockTable2.getName(LOCALE)).andReturn("ORDERFACT").anyTimes();
      expect(mockTable2.getPhysicalColumns()).andReturn(cols2).anyTimes();
      expect(mockTable2.getId()).andReturn("PT_ORDERFACT").anyTimes();
      expect(mockTable2.getProperty("target_table")).andReturn("PT_ORDERFACT").anyTimes();
  
      expect(mockCountryCol.getName(LOCALE)).andReturn("Country").anyTimes();
      expect(mockCountryCol.getName("en-US")).andReturn("Country").anyTimes();
      expect(mockCountryCol.getPhysicalTable()).andReturn(mockTable2).anyTimes();
      expect(mockCountryCol.getDataType()).andReturn(DataType.STRING);
      expect(mockCountryCol.getAggregationList()).andReturn(null);
      expect(mockCountryCol.getAggregationType()).andReturn(null);
      expect(mockCountryCol.getId()).andReturn("COUNTRY").anyTimes();
  
      expect(mockStateCol2.getName(LOCALE)).andReturn("Province").anyTimes();
      expect(mockStateCol2.getName("en-US")).andReturn("Province").anyTimes();
      expect(mockStateCol2.getPhysicalTable()).andReturn(mockTable2).anyTimes();
      expect(mockStateCol2.getDataType()).andReturn(DataType.STRING);
      expect(mockStateCol2.getAggregationList()).andReturn(null);
      expect(mockStateCol2.getAggregationType()).andReturn(null);
      expect(mockStateCol2.getId()).andReturn("PROVINCE").anyTimes();
  
      replay(mockTable1);
      replay(mockStateCol);
      replay(mockTable2);
      replay(mockCountryCol);
      replay(mockStateCol2);
  
      AvailableTable table = new AvailableTable(mockTable1);
      items.add(table);
      AvailableTable table2 = new AvailableTable(mockTable2);
      items.add(table2);
      AvailableTable table3 = new AvailableTable(mockTable2);
      table3.setFactTable(true); // tables designated as fact tables shouldn't be considered for geo fields
      items.add(table3);
      // end mock object init...
  
      // use the existing tool to generate a domain with multiple tables
      generateMultiStarTestDomain();
      // overwrite the table definitions with our mocks, so we control the columns
      workspace.getAvailableTables().setChildren(items);
  
      GeoContext geo = GeoContextFactory.create(config);
      List<DimensionMetaData> dims = geo.buildDimensions(workspace);
      assertEquals(2, dims.size());
  
  