private void fireTablesChanged() {
   // set the automodel strategy based on the number of available tables
   if (availableTables.size() > 1) {
     if (availableTables.findFactTable() != null) {
       workspaceHelper.setAutoModelStrategy(starSchemaAutoModelStrategy);
     } else {
       workspaceHelper.setAutoModelStrategy(multiTableAutoModelStrategy);
     }
   } else {
     workspaceHelper.setAutoModelStrategy(simpleAutoModelStrategy);
   }
   firePropertyChange("availableTables", null, this.availableTables); // $NON-NLS-1$
 }
  // this method signature is intended to provide a simpler path for unit testing the upConvert
  // method on its own
  protected void setDomain(Domain d, boolean upConvertDesired) {
    this.domain = d;
    this.setModelIsChanging(true);
    this.setRelationalModelIsChanging(true);
    this.model.getDimensions().clear();
    this.model.getMeasures().clear();
    this.relationalModel.getCategories().clear();
    this.availableTables.clear();

    if (upConvertDesired) {
      upConvertLegacyModel();
    }
    List<IAvailableItem> items = new ArrayList<IAvailableItem>();
    for (IPhysicalTable table : domain.getPhysicalModels().get(0).getPhysicalTables()) {
      Boolean isFact = (Boolean) table.getProperty("FACT_TABLE");
      items.add(new AvailableTable(table, isFact == null ? false : isFact.booleanValue()));
    }

    availableTables.setChildren(items);

    fireTablesChanged();

    LogicalModel lModel = domain.getLogicalModels().get(0);

    setModelName(lModel.getName(workspaceHelper.getLocale()));
    setRelationalModelName(lModel.getName(workspaceHelper.getLocale()));

    // Set the type of modeling session. This will propagate to the UI
    if (supportsOlap(domain)) {
      this.setModellingMode(ModelerMode.ANALYSIS_AND_REPORTING);
    } else {
      this.setModellingMode(ModelerMode.REPORTING_ONLY);
    }

    lModel = getLogicalModel(ModelerPerspective.ANALYSIS);
    List<OlapDimension> theDimensions = null;
    if (lModel != null) {
      theDimensions = (List) lModel.getProperty(LogicalModel.PROPERTY_OLAP_DIMS); // $NON-NLS-1$
    }
    if (theDimensions != null) {
      Iterator<OlapDimension> theDimensionItr = theDimensions.iterator();
      while (theDimensionItr.hasNext()) {
        OlapDimension theDimension = theDimensionItr.next();

        DimensionMetaData theDimensionMD =
            new DimensionMetaData(theDimension.getName(), theDimension.getType());
        theDimensionMD.setTimeDimension(theDimension.isTimeDimension());
        List<OlapHierarchy> theHierarchies = (List) theDimension.getHierarchies();
        Iterator<OlapHierarchy> theHierarchiesItr = theHierarchies.iterator();
        while (theHierarchiesItr.hasNext()) {
          OlapHierarchy theHierarchy = theHierarchiesItr.next();
          HierarchyMetaData theHierarchyMD = new HierarchyMetaData(theHierarchy.getName());

          List<OlapHierarchyLevel> theLevels = theHierarchy.getHierarchyLevels();
          Iterator<OlapHierarchyLevel> theLevelsItr = theLevels.iterator();
          while (theLevelsItr.hasNext()) {
            OlapHierarchyLevel theLevel = theLevelsItr.next();
            LevelMetaData theLevelMD = new LevelMetaData(theHierarchyMD, theLevel.getName());

            theLevelMD.setParent(theHierarchyMD);

            theLevelMD.setUniqueMembers(theLevel.isHavingUniqueMembers());
            if (theDimensionMD.isTimeDimension()) {
              TimeRole role = TimeRole.fromMondrianAttributeValue(theLevel.getLevelType());
              if (role != null) {
                theLevelMD.setDataRole(role);
              }
            }

            // Make sure we're dealing with the OLAP copy. Note that duplicated columns will have an
            // OLAP_[0-9]+ at the
            // end
            String refID;
            LogicalColumn olapCol;

            olapCol = theLevel.getReferenceColumn();
            if (olapCol != null) {
              refID = olapCol.getId();
              if (!refID.endsWith(BaseModelerWorkspaceHelper.OLAP_SUFFIX)
                  && !refID.contains(BaseModelerWorkspaceHelper.OLAP_SUFFIX + "_")) {
                olapCol = ModelerConversionUtil.findCorrespondingOlapColumn(olapCol, lModel);
                theLevel.setReferenceColumn(olapCol);
              }
              theLevelMD.setLogicalColumn(olapCol);
            }

            olapCol = theLevel.getReferenceOrdinalColumn();
            if (olapCol != null) {
              refID = olapCol.getId();
              if (!refID.endsWith(BaseModelerWorkspaceHelper.OLAP_SUFFIX)
                  && !refID.contains(BaseModelerWorkspaceHelper.OLAP_SUFFIX + "_")) {
                olapCol = ModelerConversionUtil.findCorrespondingOlapColumn(olapCol, lModel);
                theLevel.setReferenceOrdinalColumn(olapCol);
              }
              theLevelMD.setLogicalOrdinalColumn(olapCol);
            }

            olapCol = theLevel.getReferenceCaptionColumn();
            if (olapCol != null) {
              refID = olapCol.getId();
              if (!refID.endsWith(BaseModelerWorkspaceHelper.OLAP_SUFFIX)
                  && !refID.contains(BaseModelerWorkspaceHelper.OLAP_SUFFIX + "_")) {
                olapCol = ModelerConversionUtil.findCorrespondingOlapColumn(olapCol, lModel);
                theLevel.setReferenceCaptionColumn(olapCol);
              }
              theLevelMD.setLogicalCaptionColumn(olapCol);
            }
            // get any logicalColumns and turn them into member properties
            if (theLevel.getLogicalColumns() != null && theLevel.getLogicalColumns().size() > 0) {
              for (LogicalColumn lc : theLevel.getLogicalColumns()) {
                // BISERVER-11578 - Protect against null lc's in the collection. We still need to
                // investigate why this can happen in the model.
                if (lc == null) {
                  continue;
                }

                if (!lc.getId().endsWith(BaseModelerWorkspaceHelper.OLAP_SUFFIX)
                    && !lc.getId().contains(BaseModelerWorkspaceHelper.OLAP_SUFFIX + "_")) {
                  // not pointing to the olap col
                  lc = ModelerConversionUtil.findCorrespondingOlapColumn(lc, lModel);
                }
                MemberPropertyMetaData memberProp =
                    new MemberPropertyMetaData(theLevelMD, lc.getName(workspaceHelper.getLocale()));
                memberProp.setLogicalColumn(lc);
                memberProp.setDescription(lc.getDescription(workspaceHelper.getLocale()));
                theLevelMD.add(memberProp);
              }
            }
            List<OlapAnnotation> annotations = theLevel.getAnnotations();
            if (annotations != null) {
              for (OlapAnnotation anno : annotations) {
                IMemberAnnotation annoMeta = MemberAnnotationFactory.create(anno);
                theLevelMD.getMemberAnnotations().put(anno.getName(), annoMeta);
              }
            }
            theHierarchyMD.add(theLevelMD);
          }

          theHierarchyMD.setParent(theDimensionMD);
          theDimensionMD.add(theHierarchyMD);
        }
        this.model.getDimensions().add(theDimensionMD);
      }
    }
    List<OlapCube> theCubes = null;
    if (lModel != null) {
      theCubes = (List) lModel.getProperty(LogicalModel.PROPERTY_OLAP_CUBES); // $NON-NLS-1$
    }
    if (theCubes != null) {
      Iterator<OlapCube> theCubeItr = theCubes.iterator();
      while (theCubeItr.hasNext()) {
        OlapCube theCube = theCubeItr.next();

        List<OlapMeasure> theMeasures = theCube.getOlapMeasures();
        Iterator<OlapMeasure> theMeasuresItr = theMeasures.iterator();
        while (theMeasuresItr.hasNext()) {
          OlapMeasure theMeasure = theMeasuresItr.next();

          MeasureMetaData theMeasureMD = new MeasureMetaData(workspaceHelper.getLocale());

          if (theMeasure.getName() == null || theMeasure.getName().length() == 0) {
            theMeasureMD.setName(
                theMeasure.getLogicalColumn().getName(workspaceHelper.getLocale()));
          } else {
            theMeasureMD.setName(theMeasure.getName());
          }
          theMeasureMD.setFormat(
              (String) theMeasure.getLogicalColumn().getProperty("mask")); // $NON-NLS-1$
          theMeasureMD.setDefaultAggregation(theMeasure.getLogicalColumn().getAggregationType());
          String possibleMeasureName = theMeasure.getLogicalColumn().getId();
          if (!theMeasure
                  .getLogicalColumn()
                  .getId()
                  .endsWith(BaseModelerWorkspaceHelper.OLAP_SUFFIX)
              && !theMeasure
                  .getLogicalColumn()
                  .getId()
                  .contains(BaseModelerWorkspaceHelper.OLAP_SUFFIX + "_")) {
            // change the backing column to the olap version
            LogicalColumn olapCol =
                ModelerConversionUtil.findCorrespondingOlapColumn(
                    theMeasure.getLogicalColumn(), lModel);
            theMeasure.setLogicalColumn(olapCol);
          }

          // BISERVER-6077 - Mondrian exporter uses logical column names as measure names, make sure
          // they get set
          // properly
          LogicalColumn lCol = theMeasure.getLogicalColumn();
          Set<String> locales = lCol.getName().getLocales();
          String[] stringLocals = locales.toArray(new String[] {});
          if (stringLocals != null && stringLocals.length > 0) {
            if (theMeasure.getName() == null || theMeasure.getName().trim().length() == 0) {
              theMeasure.setName(possibleMeasureName);
            }
            lCol.setName(new LocalizedString(stringLocals[0], theMeasure.getName()));
          }

          theMeasureMD.setLogicalColumn(lCol);
          this.model.getMeasures().add(theMeasureMD);
        }
      }
    }

    lModel = this.getLogicalModel(ModelerPerspective.REPORTING);
    int i = 1;
    for (Category cat : lModel.getCategories()) {
      String catName =
          BaseModelerWorkspaceHelper.getCleanCategoryName(
              cat.getName(workspaceHelper.getLocale()), this, i++);
      CategoryMetaData catMeta = new CategoryMetaData(catName);
      for (LogicalColumn col : cat.getLogicalColumns()) {
        LogicalTable table = col.getLogicalTable();

        if (!table.getLogicalColumns().contains(col)) {
          table.addLogicalColumn(col);
        }

        Object formatMask = col.getProperty("mask");
        String colName = col.getName(workspaceHelper.getLocale());
        AggregationType aggType = col.getAggregationType();

        FieldMetaData field =
            new FieldMetaData(
                catMeta,
                colName,
                formatMask == null ? null : formatMask.toString(),
                colName,
                workspaceHelper.getLocale());
        if (aggType != null) {
          field.setDefaultAggregation(aggType);
        } else {
          field.setDefaultAggregation(AggregationType.NONE);
        }
        field.setLogicalColumn(col);

        catMeta.add(field);
      }
      this.getRelationalModel().getCategories().add(catMeta);
    }

    this.setModelIsChanging(false, true);
    this.setRelationalModelIsChanging(false, true);
  }
  public void refresh(Domain newDomain) throws ModelerException {

    List<IAvailableItem> items = new ArrayList<IAvailableItem>();
    for (IPhysicalTable table : newDomain.getPhysicalModels().get(0).getPhysicalTables()) {
      boolean isFact =
          table.getProperty("FACT_TABLE") != null
              ? (Boolean) table.getProperty("FACT_TABLE")
              : false;
      items.add(new AvailableTable(table, isFact));
    }

    availableTables.setChildren(items);

    setModelIsChanging(true);
    setRelationalModelIsChanging(true);

    // Set the type of modeling session. This will propigate to the UI
    if (supportsOlap(newDomain)) {
      this.setModellingMode(ModelerMode.ANALYSIS_AND_REPORTING);
    } else {
      this.setModellingMode(ModelerMode.REPORTING_ONLY);
      // clear out OLAP side of the existing model
      model.getDimensions().clear();
    }
    List<AvailableTable> tablesList = availableTables.getAsAvailableTablesList();

    fireTablesChanged();

    // replace the domain with the new domain, which
    // makes sure the physical and logical columns are accurate
    domain = newDomain;

    for (MeasureMetaData measure : model.getMeasures()) {
      boolean found = false;
      if (measure.getLogicalColumn() != null) {
        inner:
        for (AvailableTable table : tablesList) {
          for (AvailableField f : table.getAvailableFields()) {
            if (f.getPhysicalColumn()
                    .getId()
                    .equals(measure.getLogicalColumn().getPhysicalColumn().getId())
                && f.getPhysicalColumn()
                    .getPhysicalTable()
                    .getId()
                    .equals(
                        measure
                            .getLogicalColumn()
                            .getPhysicalColumn()
                            .getPhysicalTable()
                            .getId())) {
              // the physical column backing this measure is still available, set it to the new one
              measure.setLogicalColumn(
                  createColumnBackedNode(f, currentModelerPerspective).getLogicalColumn());
              found = true;
              break inner;
            }
          }
        }
        if (!found) {
          // the physical column that backed this measure no longer exists in the model.
          // therefore, we must invalidate it's logical column
          measure.setLogicalColumn(null);
        }
      }
    }

    try {
      for (DimensionMetaData dm : model.getDimensions()) {
        for (HierarchyMetaData hm : dm) {
          for (LevelMetaData lm : hm) {
            boolean found = false;
            if (lm.getLogicalColumn() != null) {
              inner:
              for (AvailableTable table : tablesList) {
                for (AvailableField f : table.getAvailableFields()) {
                  if (f.getPhysicalColumn()
                          .getId()
                          .equals(lm.getLogicalColumn().getPhysicalColumn().getId())
                      && f.getPhysicalColumn()
                          .getPhysicalTable()
                          .getId()
                          .equals(
                              lm.getLogicalColumn()
                                  .getPhysicalColumn()
                                  .getPhysicalTable()
                                  .getId())) {
                    // the physical column backing this level is still available, it is ok

                    lm.setLogicalColumn(
                        createColumnBackedNode(f, currentModelerPerspective).getLogicalColumn());
                    found = true;
                    break inner;
                  }
                }
              }
            }
            if (!found) {
              // the physical column that backed this level no longer exists in the model.
              // therefore, we must invalidate it's logical column
              lm.setLogicalColumn(null);
            }
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    for (CategoryMetaData category : relationalModel.getCategories()) {
      for (FieldMetaData field : category) {
        boolean found = false;
        if (field.getLogicalColumn() != null) {
          inner:
          for (AvailableTable table : tablesList) {
            for (AvailableField f : table.getAvailableFields()) {
              if (f.getPhysicalColumn()
                      .getId()
                      .equals(field.getLogicalColumn().getPhysicalColumn().getId())
                  && f.getPhysicalColumn()
                      .getPhysicalTable()
                      .getId()
                      .equals(
                          field
                              .getLogicalColumn()
                              .getPhysicalColumn()
                              .getPhysicalTable()
                              .getId())) {

                // the physical column backing this field is still available, it is ok
                found = true;
                break inner;
              }
            }
          }
          if (!found) {
            // the physical column that backed this field no longer exists in the model.
            // therefore, we must invalidate it's logical column
            field.setLogicalColumn(null);
          }
        }
      }
    }

    // If the new model was previously "auto-modeled" we need to clean that now
    LogicalModel newLModel = getLogicalModel(ModelerPerspective.ANALYSIS);
    if (newLModel != null) {
      List<OlapDimension> theDimensions =
          (List) newLModel.getProperty("olap_dimensions"); // $NON-NLS-1$
      if (theDimensions != null) {
        theDimensions.clear();
      }
      List<OlapCube> theCubes = (List) newLModel.getProperty("olap_cubes"); // $NON-NLS-1$
      if (theCubes != null) {
        theCubes.clear();
      }
    }

    setModelIsChanging(false);
    setRelationalModelIsChanging(false);
  }