Package nexj.core.meta.persistence.sql

Source Code of nexj.core.meta.persistence.sql.Index

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.meta.persistence.sql;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nexj.core.meta.Aspect;
import nexj.core.meta.AspectHelper;
import nexj.core.meta.Attribute;
import nexj.core.meta.Metaclass;
import nexj.core.meta.MetadataException;
import nexj.core.meta.MetadataMarker;
import nexj.core.meta.MetadataObject;
import nexj.core.meta.NamedMetadataObject;
import nexj.core.meta.Pointcut;
import nexj.core.meta.PointcutHelper;
import nexj.core.meta.Primitive;
import nexj.core.meta.persistence.Key;
import nexj.core.meta.persistence.PersistenceMapping;
import nexj.core.util.PrintWriter;
import nexj.core.util.Printable;
import nexj.core.util.StringUtil;

/**
* Index or constraint defined for a given table.
*/
public final class Index extends NamedMetadataObject implements Key, Aspect, Pointcut, Printable
{
   // constants

   /**
    * Maximum index name length.
    */
   public final static int MAX_NAME_LENGTH = 30;

   // constants

   /**
    * The index is not created in the physical schema.
    */
   public final static byte VIRTUAL = 0;

   /**
    * The index is not created in the physical schema,
    * but counts as a sort key.
    */
   public final static byte QUERY = 1;

   /**
    * The index is a template prepended to other indexes,
    * according to their aspect specification.
    */
   public final static byte ASPECT = 2;

   /**
    * Full-Text Search index.
    */
   public final static byte TEXT = 3;

   /**
    * B-tree index.
    */
   public final static byte BTREE = 4;

   /**
    * Cluster index.
    */
   public final static byte CLUSTER = 5;

   // attributes

   /**
    * The index type (BTREE, VIRTUAL, ...).
    */
   protected byte m_nType = BTREE;

   /**
    * The index page fill factor percent. 0 for the database type default. -1 for the schema default.
    */
   protected byte m_nFill = -1;

   /**
    * The unique constraint flag.
    * True if this is a unique constraint.
    */
   protected boolean m_bUnique;
  
   /**
    * True if this key is a primary key part.
    */
   protected boolean m_bPrimaryKeyPart;

   /**
    * True if the non-unique key is shared between two or more classes.
    */
   protected boolean m_bMultiplexed;

   // associations

   /**
    * The containing table.
    */
   protected Table m_table;
  
   /**
    * The index column collection.
    */
   protected List m_indexColumnList = new ArrayList(4); // of type IndexColumn

   /**
    * The related table (table providing the primary key for this foreign key).
    */
   protected Table m_relatedTable;

   /**
    * The last mapped metaclass (for multiplexing detection).
    */
   protected Metaclass m_lastMetaclass;

   /**
    * The aspect helper.
    */
   protected IndexAspectHelper m_aspectHelper;

   /**
    * The pointcut helper.
    */
   protected IndexPointcutHelper m_pointcutHelper;

   // constructors

   /**
    * Creates an index with a given name.
    * @param sName The index name.
    * @param nType The index type, one of the Index.* constants.
    * @param table The index table.
    */
   public Index(String sName, byte nType, Table table)
   {
      m_table = table;
      m_nType = nType;
      setName(sName);
   }

   /**
    * Creates an index.
    * @param table The index table.
    */
   public Index(Table table)
   {
      m_table = table;
   }

   // operations

   /**
    * @see nexj.core.meta.NamedMetadataObject#setName(java.lang.String)
    */
   public void setName(String sName)
   {
      sName = StringUtil.intern(sName); // make sure always use interned value from setName()

      if (m_nType != ASPECT && sName != null)
      {
         int nMaxLen = MAX_NAME_LENGTH;

         if (m_table != null && m_table.getSchema() != null)
         {
            String sPrefix = m_table.getSchema().getPrefix();

            if (sPrefix != null)
            {
               nMaxLen -= sPrefix.length() - sPrefix.lastIndexOf('.') - 1;

               if (nMaxLen < 0)
               {
                  nMaxLen = 0;
               }
            }
         }

         if (sName.length() > nMaxLen)
         {
            if (m_table == null || !m_table.isAspect() &&
                (m_table.getSchema() == null || m_table.getSchema().isPortable()) &&
                !m_table.isTemporary())
            {
               throw new MetadataException("err.meta.indexNameLength",
                  new Object[]{sName, Primitive.createInteger(nMaxLen)});
            }
         }
      }

      if (m_sName != null)
      {
         if (m_table != null && m_table.getSchema() != null)
         {
            if (sName != null)
            {
               Index index = m_table.getSchema().findIndex(sName);

               if (index != null && index != this)
               {
                  throw new MetadataException("err.meta.indexDup", new Object[]{sName,
                     m_table.getSchema().getDataSource().getName()});
               }
            }

            if (!m_table.isTemporary() &&
                m_table.getSchema().m_indexMap.remove(m_sName) != null &&
                sName != null)
            {
               m_table.getSchema().m_indexMap.put(sName, this);
            }
         }
      }

      super.setName(sName);
   }

   /**
    * Generates a index name for a given table.
    * @param table The new table.
    * @return The new index name.
    */
   public String getName(Table table)
   {
      String sSuffix = m_sName;
      int i = sSuffix.lastIndexOf('.');

      if (i < 0)
      {
         sSuffix = '.' + sSuffix;
      }
      else
      {
         sSuffix = sSuffix.substring(i);
      }

      return table.getName() + sSuffix;
   }

   /**
    * Sets the index type (BTREE, VIRTUAL, ...).
    * @param nType The index type (BTREE, VIRTUAL, ...) to set.
    */
   public void setType(byte nType)
   {
      verifyNotReadOnly();
      m_nType = nType;
   }

   /**
    * @return The index type (BTREE, VIRTUAL, ...).
    */
   public byte getType()
   {
      return m_nType;
   }

   /**
    * @return A string representation of the type.
    */
   public String getTypeString()
   {
      switch (m_nType)
      {
         case BTREE:
            return "btree";

         case CLUSTER:
            return "cluster";

         case VIRTUAL:
            return "virtual";

         case QUERY:
            return "query";

         case ASPECT:
            return "aspect";

         default:
            return null;
      }
   }

   /**
    * Sets the unique constraint flag.
    * @param bUnique The unique constraint flag to set.
    */
   public void setUnique(boolean bUnique)
   {
      verifyNotReadOnly();
      m_bUnique = bUnique;
   }

   /**
    * @return The unique constraint flag. True if the constraint is unique.
    */
   public boolean isUnique()
   {
      return m_bUnique;
   }

   /**
    * Sets the index page fill factor percent.
    * @param nFill The default index page fill factor percent to set.
    */
   public void setFill(int nFill)
   {
      verifyNotReadOnly();

      if (nFill < -1 || nFill > 100)
      {
         throw new MetadataException("err.meta.indexFill",
            new Object[]{Primitive.createInteger(nFill), getName()});
      }

      m_nFill = (byte)nFill;
   }

   /**
    * @return The index page fill factor percent.
    */
   public byte getFill()
   {
      return m_nFill;
   }

   /**
    * Sets the containing table.
    * @param table The containing table.
    */
   public void setTable(Table table)
   {
      verifyNotReadOnly();
      m_table = table;
   }

   /**
    * @return The containing table.
    */
   public Table getTable()
   {
      return m_table;
   }

   /**
    * Adds a new index column to the index in a specified position.
    * @param nOrdinal The column ordinal number, 0-based.
    * @param indexColumn The index column to add.
    */
   public void addIndexColumn(int nOrdinal, IndexColumn indexColumn)
   {
      verifyNotReadOnly();
      indexColumn.setOrdinal(nOrdinal);

      if (findIndexColumn(indexColumn.getColumn()) != null)
      {
         throw new MetadataException("err.meta.indexColumnDup",
            new Object[]{indexColumn.getColumn().getName(), getName()});
      }

      // address TT #41674 with arbitrary limits defined in Column
      if (getType() != TEXT && // TEXT indexes may contain LOB columns
          indexColumn.getColumn().isLOB(Column.MAX_NVARCHAR_PRECISION,
                                        Column.MAX_VARBINARY_PRECISION))
      {
         throw new MetadataException("err.meta.indexColumnLocator",
            new Object[]{indexColumn.getColumn().getName(), getName()});
      }

      m_indexColumnList.add(nOrdinal, indexColumn);
      indexColumn.setIndex(this);

      for (int i = nOrdinal + 1, n = m_indexColumnList.size(); i < n; ++i)
      {
         ((IndexColumn)m_indexColumnList.get(i)).setOrdinal(i);
      }
   }

   /**
    * Adds a new index column to the index.
    * @param indexColumn The index column to add.
    */
   public void addIndexColumn(IndexColumn indexColumn)
   {
      addIndexColumn(m_indexColumnList.size(), indexColumn);
   }

   /**
    * Removes an index column.
    * @param indexColumn The index column to remove.
    */
   public void removeIndexColumn(IndexColumn indexColumn)
   {
      verifyNotReadOnly();

      int i = indexColumn.getOrdinal();

      assert m_indexColumnList.get(i) == indexColumn;

      m_indexColumnList.remove(i);
      indexColumn.setOrdinal(-1);

      for (int n = m_indexColumnList.size(); i < n; ++i)
      {
         ((IndexColumn)m_indexColumnList.get(i)).setOrdinal(i);
      }
   }

   /**
    * Gets a index column by ordinal number.
    * @param nOrdinal The index column ordinal number (0-based).
    * @return The index column object.
    */
   public IndexColumn getIndexColumn(int nOrdinal)
   {
      return (IndexColumn)m_indexColumnList.get(nOrdinal);
   }

   /**
    * @return The index column count.
    */
   public int getIndexColumnCount()
   {
      return m_indexColumnList.size();
   }

   /**
    * @return An iterator for the contained index column objects.
    */
   public Iterator getIndexColumnIterator()
   {
      return m_indexColumnList.iterator();
   }

   /**
    * Finds an index column object by column.
    * @param column The column by which to search.
    * @return The index column object, or null if not found.
    */
   public IndexColumn findIndexColumn(Column column)
   {
      for (int i = 0, n = getIndexColumnCount(); i < n; ++i)
      {
         IndexColumn indexColumn = getIndexColumn(i);

         if (indexColumn.getColumn() == column)
         {
            return indexColumn;
         }
      }

      return null;
   }

   /**
    * Finds an index column object by column name.
    * @param sName The column name by which to search.
    * @return The index column object, or null if not found.
    */
   public IndexColumn findIndexColumn(String sName)
   {
      for (int i = 0, n = getIndexColumnCount(); i < n; ++i)
      {
         IndexColumn indexColumn = getIndexColumn(i);

         if (indexColumn.getColumn().getName().equals(sName))
         {
            return indexColumn;
         }
      }

      return null;
   }

   /**
    * Sets the related table (table providing the primary key for this foreign key).
    * @param relatedTable The related table (table providing the primary key for this foreign key) to set.
    * @throws MetadataException if the related table is an aspect.
    */
   public void setRelatedTable(Table relatedTable) throws MetadataException
   {
      verifyNotReadOnly();
     
      if (relatedTable != null &&
         relatedTable.isAspect())
      {
         throw new MetadataException("err.meta.persistence.sql.relatedTableAspect",
            new Object[]{relatedTable.getTableName(), m_sName, m_table.getSchema().getDataSource().getName()});
      }

      m_relatedTable = relatedTable;
   }

   /**
    * @return The related table (table providing the primary key for this foreign key).
    */
   public Table getRelatedTable()
   {
      return m_relatedTable;
   }
  
   /**
    * Checks if this key can be used in a natural join with another key.
    * @param index The index to compare against this index.
    * @return true if the keys are compatible.
    */
   public boolean isCompatible(Index index)
   {
      return PersistenceMapping.compatible(this, index);
   }

   /**
    * @see nexj.core.meta.persistence.Key#getPartType(int)
    */
   public Primitive getPartType(int nOrdinal)
   {
      return getIndexColumn(nOrdinal).getColumn().getType();
   }

   /**
    * @see nexj.core.meta.persistence.Key#isPartAscending(int)
    */
   public boolean isPartAscending(int nOrdinal)
   {
      return getIndexColumn(nOrdinal).isAscending();
   }

   /**
    * @see nexj.core.meta.persistence.Key#getPartCount()
    */
   public int getPartCount()
   {
      return getIndexColumnCount();
   }
  
   /**
    * @see nexj.core.meta.persistence.Key#isObjectKey()
    */
   public boolean isObjectKey()
   {
      return this == m_table.getPrimaryKey();
   }

   /**
    * @see nexj.core.meta.persistence.Key#isObjectKeyPart()
    */
   public boolean isObjectKeyPart()
   {
      return m_bPrimaryKeyPart;
   }

   /**
    * @see nexj.core.meta.persistence.Key#getObjectKeyPartOrdinal(int)
    */
   public int getObjectKeyPartOrdinal(int nOrdinal)
   {
      return getIndexColumn(nOrdinal).getPrimaryKeyPartOrdinal();
   }

   /**
    * Computes the primary key parts.
    */
   public void computePrimaryKeyParts()
   {
      verifyNotReadOnly();
     
      Index pk = m_table.getPrimaryKey();

      if (pk == null)
      {
         return;
      }

      m_bPrimaryKeyPart = true;

      if (this == pk)
      {
         for (int i = 0, nCount = getIndexColumnCount(); i < nCount; ++i)
         {
            IndexColumn indexColumn = getIndexColumn(i);
           
            indexColumn.setPrimaryKeyPartOrdinal(i);
            indexColumn.getColumn().setPrimary(true);
         }
      }
      else
      {
         for (int i = 0, nCount = getIndexColumnCount(); i < nCount; ++i)
         {
            IndexColumn icol = getIndexColumn(i);
            IndexColumn icolPK = pk.findIndexColumn(icol.getColumn());
           
            if (icolPK == null)
            {
               m_bPrimaryKeyPart = false;
            }
            else
            {
               icol.setPrimaryKeyPartOrdinal(icolPK.getOrdinal());
            }
         }
      }
   }

   /**
    * Adds a mapped attribute to the key.
    * @param attribute The attribute to add.
    */
   public void addAttribute(Attribute attribute)
   {
      verifyNotReadOnly();

      Metaclass metaclass = (Metaclass)attribute.getType();

      if (m_table.isAspect() != (metaclass instanceof Aspect && ((Aspect)metaclass).isAspect()))
      {
         throw new MetadataException((m_table.isAspect()) ?
            "err.meta.persistence.sql.classKeyAspectMismatch" :
            "err.meta.persistence.sql.classAspectKeyMismatch",
            new Object[]{attribute.getName(), metaclass.getName(),
               m_sName, m_table.getName()});
      }

      if (!m_bUnique)
      {
         if (m_lastMetaclass != null)
         {
            if (metaclass != m_lastMetaclass)
            {
               m_bMultiplexed = true;
            }
         }
         else
         {
            m_lastMetaclass = metaclass;
         }
        
         m_bMultiplexed |= m_bPrimaryKeyPart;
      }
   }

   /**
    * @return True if the non-unique key is shared between two or more metaclasses.
    */
   public boolean isMultiplexed()
   {
      return m_bMultiplexed;
   }

   /**
    * @see nexj.core.meta.persistence.Key#setMapped()
    */
   public void setMapped()
   {
      for (int i = getIndexColumnCount() - 1; i >= 0; --i)
      {
         getIndexColumn(i).getColumn().setCaseInsensitive(false);
      }
   }

   /**
    * @see nexj.core.meta.Pointcut#isPointcut()
    */
   public boolean isPointcut()
   {
      return m_nType != ASPECT;
   }

   /**
    * @see nexj.core.meta.Pointcut#addAspect(nexj.core.meta.Aspect)
    */
   public void addAspect(Aspect aspect) throws MetadataException
   {
      verifyNotReadOnly();

      if (m_pointcutHelper == null)
      {
         m_pointcutHelper = new IndexPointcutHelper(this);
      }

      m_pointcutHelper.addAspect(aspect);
   }

   /**
    * @see nexj.core.meta.Pointcut#removeAspect(nexj.core.meta.Aspect)
    */
   public boolean removeAspect(Aspect aspect)
   {
      if (m_pointcutHelper != null)
      {
         return m_pointcutHelper.removeAspect(aspect);
      }

      return false;
   }

   /**
    * @see nexj.core.meta.Pointcut#getAspect(int)
    */
   public Aspect getAspect(int nOrdinal)
   {
      return m_pointcutHelper.getAspect(nOrdinal);
   }

   /**
    * @see nexj.core.meta.Pointcut#hasAspect(nexj.core.meta.Aspect)
    */
   public boolean hasAspect(Aspect aspect)
   {
      if (m_pointcutHelper == null)
      {
         return false;
      }

      return m_pointcutHelper.hasAspect(aspect);
   }

   /**
    * @see nexj.core.meta.Pointcut#getAspectCount()
    */
   public int getAspectCount()
   {
      if (m_pointcutHelper == null)
      {
         return 0;
      }

      return m_pointcutHelper.getAspectCount();
   }

   /**
    * @see nexj.core.meta.Pointcut#addAspectOverride(nexj.core.meta.Aspect, boolean)
    */
   public void addAspectOverride(Aspect aspect, boolean bInclusive) throws MetadataException
   {
      verifyNotReadOnly();

      if (isAspect())
      {
         throw new MetadataException("err.meta.nestedIndexAspect",
            new Object[]{m_sName});
      }

      if (!aspect.isAspect())
      {
         throw new MetadataException("err.meta.indexAspectType",
            new Object[]{aspect.getName(), m_sName});
      }

      if (m_pointcutHelper == null)
      {
         m_pointcutHelper = new IndexPointcutHelper(this);
      }

      m_pointcutHelper.addAspectOverride(aspect, bInclusive);
   }

   /**
    * @see nexj.core.meta.Pointcut#removeAspectOverride(nexj.core.meta.Aspect)
    */
   public final boolean removeAspectOverride(Aspect aspect)
   {
      if (m_pointcutHelper != null)
      {
         return m_pointcutHelper.removeAspectOverride(aspect);
      }

      return false;
   }

   /**
    * @see nexj.core.meta.Pointcut#findAspectOverride(nexj.core.meta.Aspect)
    */
   public int findAspectOverride(Aspect aspect)
   {
      if (m_pointcutHelper == null)
      {
         return -1;
      }

      return m_pointcutHelper.findAspectOverride(aspect);
   }

   /**
    * @see nexj.core.meta.Pointcut#getAspectOverride(int)
    */
   public Aspect getAspectOverride(int nOrdinal)
   {
      return m_pointcutHelper.getAspectOverride(nOrdinal);
   }

   /**
    * @see nexj.core.meta.Pointcut#isAspectOverrideInclusive(int)
    */
   public boolean isAspectOverrideInclusive(int nOrdinal)
   {
      return m_pointcutHelper.isAspectOverrideInclusive(nOrdinal);
   }

   /**
    * @see nexj.core.meta.Pointcut#getAspectOverrideCount()
    */
   public int getAspectOverrideCount()
   {
      if (m_pointcutHelper == null)
      {
         return 0;
      }

      return m_pointcutHelper.getAspectOverrideCount();
   }

   /**
    * @see nexj.core.meta.Aspect#isAspect()
    */
   public boolean isAspect()
   {
      return m_nType == ASPECT;
   }

   /**
    * @see nexj.core.meta.Aspect#addPointcutPattern(java.lang.String, boolean)
    */
   public void addPointcutPattern(String sPattern, boolean bInclusive)
   {
      verifyNotReadOnly();

      if (!isAspect())
      {
         throw new MetadataException("err.meta.indexPointcut",
            new Object[]{m_sName});
      }

      if (m_aspectHelper == null)
      {
         m_aspectHelper = new IndexAspectHelper(this);
      }

      m_aspectHelper.addPointcutPattern(sPattern, bInclusive);
   }

   /**
    * @see nexj.core.meta.Aspect#getPointcutPattern(int)
    */
   public String getPointcutPattern(int nOrdinal)
   {
      return m_aspectHelper.getPointcutPattern(nOrdinal);
   }

   /**
    * @see nexj.core.meta.Aspect#isPointcutPatternInclusive(int)
    */
   public boolean isPointcutPatternInclusive(int nOrdinal)
   {
      return m_aspectHelper.isPointcutPatternInclusive(nOrdinal);
   }

   /**
    * @see nexj.core.meta.Aspect#getPointcutPatternCount()
    */
   public int getPointcutPatternCount()
   {
      if (m_aspectHelper == null)
      {
         return 0;
      }

      return m_aspectHelper.getPointcutPatternCount();
   }

   /**
    * @see nexj.core.meta.Aspect#isMatching(nexj.core.meta.Pointcut)
    */
   public boolean isMatching(Pointcut pointcut)
   {
      if (m_aspectHelper == null)
      {
         return false;
      }
     
      return m_aspectHelper.isMatching(pointcut);
   }

   /**
    * @see nexj.core.meta.Aspect#addTo(nexj.core.meta.Pointcut)
    */
   public void addTo(Pointcut pointcut)
   {
      AspectHelper helper = m_aspectHelper;

      if (helper == null && m_nType == ASPECT)
      {
         helper = new IndexAspectHelper(this);
      }

      if (helper != null)
      {
         helper.addTo(pointcut);
      }
   }

   /**
    * @see nexj.core.meta.Aspect#applyTo(nexj.core.meta.Pointcut, int)
    */
   public void applyTo(Pointcut pointcut, int nPass) throws MetadataException
   {
      Index index = (Index)pointcut;

      for (int i = 0, n = getIndexColumnCount(); i < n; ++i)
      {
         IndexColumn indexColumn = getIndexColumn(i);

         index.addIndexColumn(i, new IndexColumn(
            index.getTable().getColumn(indexColumn.getColumn().getName()),
               indexColumn.isAscending()));
      }
   }

   /**
    * @see nexj.core.meta.Aspect#removeFrom(nexj.core.meta.Pointcut)
    */
   public boolean removeFrom(Pointcut pointcut)
   {
      if (pointcut.removeAspect(this))
      {
         Index index = (Index)pointcut;

         for (int i = 0, n = getIndexColumnCount(); i < n; ++i)
         {
            IndexColumn indexColumn = index.findIndexColumn(getIndexColumn(i).getColumn().getName());

            if (indexColumn != null)
            {
               index.removeIndexColumn(indexColumn);
            }
         }

         return true;
      }

      return false;
   }

   /**
    * @return True if the index is inherited.
    */
   public boolean isInherited()
   {
      for (int i = 0, n = m_table.getAspectCount(); i < n; ++i)
      {
         Table aspect = (Table)m_table.getAspect(i);

         for (int k = 0, m = aspect.getIndexCount(); k < m; ++k)
         {
            if (m_sName.equals(aspect.getIndex(k).getName(m_table)))
            {
               return true;
            }
         }
      }

      return false;
   }

   /**
    * @see nexj.core.meta.MetadataObject#makeReadOnly()
    */
   public void makeReadOnly()
   {
      for (Iterator itr = getIndexColumnIterator(); itr.hasNext();)
      {
         ((MetadataObject)itr.next()).makeReadOnly();
      }

      super.makeReadOnly();

      ((ArrayList)m_indexColumnList).trimToSize(); // free unused memory
   }

   /**
    * @see nexj.core.meta.MetadataObject#setProperties(nexj.core.meta.MetadataMarker)
    */
   public void setProperties(MetadataMarker marker)
   {
      marker.setTypeName("Index");
      marker.setProperty("dataSource", m_table.getSchema().getDataSource().getName());
      marker.setProperty("table", m_table.getName());
      marker.setProperty("index", m_sName);
   }

   /**
    * Clones the index (deep copy).
    * @param table The new table instance.
    * @see nexj.core.meta.MetadataObject#clone()
    */
   protected Index clone(final Table table)
   {
      Index index = (Index)super.clone();

      index.m_table = table;
      index.m_indexColumnList = new ArrayList(m_indexColumnList.size());

      for (int i = 0, n = m_indexColumnList.size(); i < n; ++i)
      {
         index.m_indexColumnList.add(((IndexColumn)m_indexColumnList.get(i)).clone(index));
      }

      if (m_pointcutHelper != null)
      {
         index.m_pointcutHelper = (IndexPointcutHelper)m_pointcutHelper.clone(
            new PointcutHelper.AspectLookup()
            {
               public Aspect get(String sName) throws MetadataException
               {
                  return table.getSchema().getIndex(sName);
               }
            });
         index.m_pointcutHelper.m_index = index;
      }

      if (m_aspectHelper != null)
      {
         index.m_aspectHelper = (IndexAspectHelper)m_aspectHelper.clone();
         index.m_aspectHelper.m_index = index;
      }
     
      return index;
   }

   /**
    * @see nexj.core.util.Printable#printOn(nexj.core.util.PrintWriter)
    */
   public void printOn(PrintWriter writer) throws IOException
   {
      writer.write("Index ");
      writer.write(m_sName);
   }

   /**
    * @see nexj.core.meta.NamedMetadataObject#toString()
    */
   public String toString()
   {
      return PrintWriter.toString(this);
   }

   // inner classes

   /**
    * Index-specific aspect helper.
    */
   protected final static class IndexAspectHelper extends AspectHelper
   {
      protected Index m_index;

      public IndexAspectHelper(Index index)
      {
         m_index = index;
      }

      /**
       * @see nexj.core.meta.AspectHelper#getContainer()
       */
      protected Aspect getContainer()
      {
         return m_index;
      }
   }

   /**
    * Index-specific pointcut helper.
    */
   protected final static class IndexPointcutHelper extends PointcutHelper
   {
      protected Index m_index;

      public IndexPointcutHelper(Index index)
      {
         m_index = index;
      }

      /**
       * @see nexj.core.meta.PointcutHelper#getContainer()
       */
      protected Pointcut getContainer()
      {
         return m_index;
      }

      /**
       * @see nexj.core.meta.PointcutHelper#getContainerType()
       */
      protected String getContainerType()
      {
         return "index";
      }
   }
}
TOP

Related Classes of nexj.core.meta.persistence.sql.Index

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.