Package org.pentaho.platform.plugin.services.metadata

Source Code of org.pentaho.platform.plugin.services.metadata.PentahoMetadataDomainRepository

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, version 2 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details.
*
*
* Copyright 2006 - 2013 Pentaho Corporation.  All rights reserved.
*/

package org.pentaho.platform.plugin.services.metadata;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.metadata.model.Domain;
import org.pentaho.metadata.model.LogicalModel;
import org.pentaho.metadata.model.concept.IConcept;
import org.pentaho.metadata.repository.DomainAlreadyExistsException;
import org.pentaho.metadata.repository.DomainIdNullException;
import org.pentaho.metadata.repository.DomainStorageException;
import org.pentaho.metadata.repository.IMetadataDomainRepository;
import org.pentaho.metadata.util.LocalizationUtil;
import org.pentaho.metadata.util.XmiParser;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException;
import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData;
import org.pentaho.platform.plugin.services.messages.Messages;
import org.pentaho.platform.repository2.unified.RepositoryUtils;
import org.pentaho.platform.repository2.unified.fileio.RepositoryFileInputStream;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;

/**
* Handles the storage and retrieval of Pentaho Metada Domain objects in a repository. It does this by using a
* pre-defined system location (defined by {@link PentahoMetadataDomainRepositoryInfo}) as the storage location for the
* Domain files and associated locale files. </p> Since Domain IDs are the unique identifier for Pentaho Metadata
* domains and may contain any character (including repository folder separator character(s) like '/', a {@link UUID}
* will be created to store each file. The metadata for the file will be used to store the information (such as the
* Domain ID). </p>
*
* @author <a href="mailto:dkincade@pentaho.com">David M. Kincade</a>
*/
public class PentahoMetadataDomainRepository implements IMetadataDomainRepository,
    IPentahoMetadataDomainRepositoryImporter, IPentahoMetadataDomainRepositoryExporter {
  // The logger for this class
  private static final Log logger = LogFactory.getLog( PentahoMetadataDomainRepository.class );

  // The messages object used in generating messages that may be seen by the user
  private static final Messages messages = Messages.getInstance();

  private static final Map<IUnifiedRepository, PentahoMetadataInformationMap> metaMapStore =
      new HashMap<IUnifiedRepository, PentahoMetadataInformationMap>();

  // The type of repository file (domain, locale)
  private static final String PROPERTY_NAME_TYPE = "file-type";

  private static final String TYPE_DOMAIN = "domain";
  private static final String TYPE_LOCALE = "locale";

  // The repository file metadata key used to store the file's domain id
  private static final String PROPERTY_NAME_DOMAIN_ID = "domain-id";

  // The repository file metadata key used to store the file's locale (properties files)
  private static final String PROPERTY_NAME_LOCALE = "locale";

  // The default encoding for file storage
  private static final String DEFAULT_ENCODING = "UTF-8";

  // The default mime-type for the Pentaho Domain files
  private static final String DOMAIN_MIME_TYPE = "text/xml";

  // The default mime-type for locale files
  private static final String LOCALE_MIME_TYPE = "text/plain";

  // The repository used to store / retrieve objects
  private IUnifiedRepository repository;

  // Mapping between the Pentaho Metadata Domain ID and the repository files for that Domain
  private final PentahoMetadataInformationMap metadataMapping;

  // The parser used to serialize / deserialize metadata files
  private XmiParser xmiParser;

  // The repository utility class
  private RepositoryUtils repositoryUtils;

  // The localization utility class (used to load side-car properties files into a Domain object)
  private LocalizationUtil localizationUtil;

  /**
   * Creates an instance of this class providing the {@link IUnifiedRepository} repository backend.
   *
   * @param repository
   *          the {@link IUnifiedRepository} in which data will be stored / retrieved
   */
  public PentahoMetadataDomainRepository( final IUnifiedRepository repository ) {
    this( repository, null, null, null );
  }

  /**
   * Helper constructor used for setting other objects in this class
   *
   * @param repository
   *          the {@link IUnifiedRepository} in which data will be stored / retrieved
   * @param repositoryUtils
   *          utility class for working inside the repository </br>(NOTE: {@code null} is acceptable and will create a
   *          default instance)
   * @param xmiParser
   *          the parser class for serializing / de-serializing Domain objects </br>(NOTE: {@code null} is acceptable
   *          and will create a default instance)
   * @param localizationUtil
   *          the object used to add locale bundles into a Pentaho Metadata Domain object </br>(NOTE: {@code null} is
   *          acceptable and will create a default instance)
   */
  protected PentahoMetadataDomainRepository( final IUnifiedRepository repository,
      final RepositoryUtils repositoryUtils, final XmiParser xmiParser, final LocalizationUtil localizationUtil ) {
    if ( null == repository ) {
      throw new IllegalArgumentException();
    }
    this.metadataMapping = getMetadataMapping( repository );
    setRepository( repository );
    setRepositoryUtils( repositoryUtils );
    setLocalizationUtil( localizationUtil );
    setXmiParser( xmiParser );
  }

  /**
   * Store a domain to the repository. The domain should persist between JVM restarts.
   *
   * @param domain
   *          domain object to store
   * @param overwrite
   *          if true, overwrite existing domain
   * @throws DomainIdNullException
   *           if domain id is null or empty
   * @throws DomainAlreadyExistsException
   *           if a domain with the same Domain ID already exists in the repository and {@code overwrite == false}
   * @throws DomainStorageException
   *           if there is a problem storing the domain
   */
  @Override
  public void storeDomain( final Domain domain, final boolean overwrite ) throws DomainIdNullException,
    DomainAlreadyExistsException, DomainStorageException {
    logger.debug( "storeDomain(domain(id=" + ( domain != null ? domain.getId() : "" ) + ", " + overwrite + ")" );
    if ( null == domain || StringUtils.isEmpty( domain.getId() ) ) {
      throw new DomainIdNullException( messages
          .getErrorString( "PentahoMetadataDomainRepository.ERROR_0001_DOMAIN_ID_NULL" ) );
    }

    String xmi = "";
    try {
      // NOTE - a ByteArrayInputStream doesn't need to be closed ...
      // ... so this is safe AS LONG AS we use a ByteArrayInputStream
      xmi = xmiParser.generateXmi( domain );
      //final InputStream inputStream = new ByteArrayInputStream( xmi.getBytes( DEFAULT_ENCODING ) );
      final InputStream inputStream = new ByteArrayInputStream( xmi.getBytes( "UTF8" ) );
      storeDomain( inputStream, domain.getId(), overwrite );
    } catch ( DomainStorageException dse ) {
      throw dse;
    } catch ( DomainAlreadyExistsException dae ) {
      throw dae;
    } catch ( Exception e ) {
      final String errorMessage =
          messages.getErrorString( "PentahoMetadataDomainRepository.ERROR_0003_ERROR_STORING_DOMAIN", domain.getId(), e
              .getLocalizedMessage() );
      logger.error( errorMessage, e );
      throw new DomainStorageException( xmi + errorMessage, e );
    }
  }

  /**
   * Stores a domain to the repository directly as an Input Stream
   *
   * @param inputStream
   * @param domainId
   * @param overwrite
   */
  @Override
  public void storeDomain( final InputStream inputStream, final String domainId, final boolean overwrite )
    throws DomainIdNullException, DomainAlreadyExistsException, DomainStorageException {
    logger.debug( "storeDomain(inputStream, " + domainId + ", " + overwrite + ")" );
    if ( null == inputStream ) {
      throw new IllegalArgumentException();
    }
    if ( StringUtils.isEmpty( domainId ) ) {
      throw new DomainIdNullException( messages
          .getErrorString( "PentahoMetadataDomainRepository.ERROR_0001_DOMAIN_ID_NULL" ) );
    }

    // Check to see if the domain already exists
    final RepositoryFile domainFile = getMetadataRepositoryFile( domainId );
    if ( !overwrite && domainFile != null ) {
      final String errorString =
          messages.getErrorString( "PentahoMetadataDomainRepository.ERROR_0002_DOMAIN_ALREADY_EXISTS", domainId );
      logger.error( errorString );
      throw new DomainAlreadyExistsException( errorString );
    }

    // Check if this is valid xml
    InputStream inputStream2 = null;
    String xmi = null;
    try {
      // try to see if the xmi can be parsed (ie, check if it's valid xmi)
      // first, convert our input stream to a string
      BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream, DEFAULT_ENCODING ) );
      StringBuilder stringBuilder = new StringBuilder();
      while ( ( xmi = reader.readLine() ) != null ) {
        stringBuilder.append( xmi );
      }
      inputStream.close();
      xmi = stringBuilder.toString();
      // now, try to see if the xmi can be parsed (ie, check if it's valid xmi)
      Domain domain = xmiParser.parseXmi( new java.io.ByteArrayInputStream( xmi.getBytes( DEFAULT_ENCODING ) ) );
      // xmi is valid. Create a new inputstream for the actual import action.
      inputStream2 = new java.io.ByteArrayInputStream( xmi.getBytes( DEFAULT_ENCODING ) );
    } catch ( Exception ex ) {
      logger.error( ex.getMessage() );
      // throw new
      // DomainStorageException(messages.getErrorString("PentahoMetadataDomainRepository.ERROR_0010_ERROR_PARSING_XMI"),
      // ex);
      java.io.ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      ex.printStackTrace( new java.io.PrintStream( byteArrayOutputStream ) );
      throw new DomainStorageException( byteArrayOutputStream.toString(), ex );
    }

    final SimpleRepositoryFileData data =
        new SimpleRepositoryFileData( inputStream2, DEFAULT_ENCODING, DOMAIN_MIME_TYPE );
    if ( domainFile == null ) {
      final RepositoryFile newDomainFile = createUniqueFile( domainId, null, data );
    } else {
      repository.updateFile( domainFile, data, null );
    }

    // This invalidates any caching
    flushDomains();

  }

  /*
   * retrieves the data streams for the metadata referenced by domainId. This could be a single .xmi file or an .xmi
   * file and multiple .properties files.
   */
  public Map<String, InputStream> getDomainFilesData( final String domainId ) {
    Map<String, InputStream> values = new HashMap<String, InputStream>();
    Set<RepositoryFile> metadataFiles;
    synchronized ( metadataMapping ) {
      metadataFiles = metadataMapping.getFiles( domainId );
    }
    for ( RepositoryFile repoFile : metadataFiles ) {
      RepositoryFileInputStream is;
      try {
        is = new RepositoryFileInputStream( repoFile );
      } catch ( Exception e ) {
        return null; // This pretty much ensures an exception will be thrown later and passed to the client
      }
      String fileName = repoFile.getName().endsWith( ".properties" ) ? repoFile.getName()
          : domainId + ( domainId.endsWith( ".xmi" ) ? "" : ".xmi" );
      values.put( fileName, is );
    }
    return values;
  }

  /**
   * retrieve a domain from the repo. This does lazy loading of the repo, so it calls reloadDomains() if not already
   * loaded.
   *
   * @param domainId
   *          domain to get from the repository
   * @return domain object
   */
  @Override
  public Domain getDomain( final String domainId ) {
    logger.debug( "getDomain(" + domainId + ")" );
    if ( StringUtils.isEmpty( domainId ) ) {
      throw new IllegalArgumentException( messages.getErrorString(
          "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId ) );
    }

    Domain domain = null;
    try {
      // Load the domain file
      final RepositoryFile file = getMetadataRepositoryFile( domainId );
      if ( file != null ) {
        SimpleRepositoryFileData data = repository.getDataForRead( file.getId(), SimpleRepositoryFileData.class );
        if ( data != null ) {
          domain = xmiParser.parseXmi( data.getStream() );
          domain.setId( domainId );
          logger.debug( "loaded domain" );

          // Load any I18N bundles
          loadLocaleStrings( domainId, domain );
          logger.debug( "loaded I18N bundles" );
        } else {
          throw new UnifiedRepositoryException( messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0005_ERROR_RETRIEVING_DOMAIN", domainId, "not found" ) );

        }
      }
    } catch ( Exception e ) {
      throw new UnifiedRepositoryException( messages.getErrorString(
          "PentahoMetadataDomainRepository.ERROR_0005_ERROR_RETRIEVING_DOMAIN",
        domainId, e.getLocalizedMessage() ), e );
    }

    // Return
    return domain;
  }

  /**
   * return a list of all the domain ids in the repository. triggers a call to reloadDomains if necessary.
   *
   * @return the domain Ids.
   */
  @Override
  public Set<String> getDomainIds() {
    logger.debug( "getDomainIds()" );
    internalReloadDomains();
    final Set<String> domainIds = new HashSet<String>();
    synchronized ( metadataMapping ) {
      domainIds.addAll( metadataMapping.getDomainIds() );
      return domainIds;
    }
  }

  /**
   * remove a domain from disk and memory.
   *
   * @param domainId
   */
  @Override
  public void removeDomain( final String domainId ) {
    logger.debug( "removeDomain(" + domainId + ")" );
    if ( StringUtils.isEmpty( domainId ) ) {
      throw new IllegalArgumentException( messages.getErrorString(
          "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId ) );
    }

    // Get the metadata domain file
    Set<RepositoryFile> domainFiles;
    synchronized ( metadataMapping ) {
      domainFiles = metadataMapping.getFiles( domainId );
      metadataMapping.deleteDomain( domainId );
    }

    for ( final RepositoryFile file : domainFiles ) {
      if ( logger.isTraceEnabled() ) {
        logger.trace( "Deleting repository file " + toString( file ) );
      }
      repository.deleteFile( file.getId(), true, null );
    }

    // This invalidates any caching
    if ( !domainFiles.isEmpty() ) {
      flushDomains();
    }

  }

  /**
   * remove a model from a domain which is stored either on a disk or memory.
   *
   * @param domainId
   * @param modelId
   */
  @Override
  public void removeModel( final String domainId, final String modelId ) throws DomainIdNullException,
    DomainStorageException {
    logger.debug( "removeModel(" + domainId + ", " + modelId + ")" );
    if ( StringUtils.isEmpty( domainId ) ) {
      throw new IllegalArgumentException( messages.getErrorString(
          "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId ) );
    }
    if ( StringUtils.isEmpty( modelId ) ) {
      throw new IllegalArgumentException( messages
          .getErrorString( "PentahoMetadataDomainRepository.ERROR_0006_MODEL_ID_INVALID" ) );
    }

    // Get the domain and remove the model
    final Domain domain = getDomain( domainId );
    if ( null != domain ) {
      boolean found = false;
      final Iterator<LogicalModel> iter = domain.getLogicalModels().iterator();
      while ( iter.hasNext() ) {
        LogicalModel model = iter.next();
        if ( modelId.equals( model.getId() ) ) {
          iter.remove();
          found = true;
          break;
        }
      }

      // Update the domain if we change it
      if ( found ) {
        try {
          storeDomain( domain, true );
          flushDomains();
        } catch ( DomainAlreadyExistsException ignored ) {
          // This can't happen since we have setup overwrite to true
        }
      }
    }
  }

  /**
   * reload domains from disk
   */
  @Override
  public void reloadDomains() {
    logger.debug( "reloadDomains()" );
    internalReloadDomains();
  }

  /**
   * Performs the process of reloading the domain information from the repository
   */
  private void internalReloadDomains() {
    synchronized ( metadataMapping ) {
      metadataMapping.reset();

      // Reload the metadata about the metadata (that was fun to say)
      final List<RepositoryFile> children = repository.getChildren( getMetadataDir().getId(), "*" );
      logger.trace( "\tFound " + children.size() + " files in the repository" );
      for ( final RepositoryFile child : children ) {
        // Get the metadata for this file
        final Map<String, Serializable> fileMetadata = repository.getFileMetadata( child.getId() );
        if ( fileMetadata == null || StringUtils.isEmpty( (String) fileMetadata.get( PROPERTY_NAME_DOMAIN_ID ) ) ) {
          logger.warn( messages.getString( "PentahoMetadataDomainRepository.WARN_0001_FILE_WITHOUT_METADATA", child
              .getName() ) );
          continue;
        }
        final String domainId = (String) fileMetadata.get( PROPERTY_NAME_DOMAIN_ID );
        final String type = (String) fileMetadata.get( PROPERTY_NAME_TYPE );
        final String locale = (String) fileMetadata.get( PROPERTY_NAME_LOCALE );
        if ( logger.isTraceEnabled() ) {
          logger.trace( "\tprocessing file [type=" + type + " : domainId=" + domainId + " : locale=" + locale + "]" );
        }

        // Save the data in the map
        if ( StringUtils.equals( type, TYPE_DOMAIN ) ) {
          metadataMapping.addDomain( domainId, child );
        } else if ( StringUtils.equals( type, TYPE_LOCALE ) ) {
          metadataMapping.addLocale( domainId, locale, child );
        }
      }
    }
  }

  /**
   * flush the domains from memory
   */
  @Override
  public void flushDomains() {
    logger.debug( "flushDomains()" );
    internalReloadDomains();
  }

  @Override
  public String generateRowLevelSecurityConstraint( final LogicalModel model ) {
    // We will let subclasses handle this issue
    return null;
  }

  /**
   * The aclHolder cannot be null unless the access type requested is ACCESS_TYPE_SCHEMA_ADMIN.
   */
  @Override
  public boolean hasAccess( final int accessType, final IConcept aclHolder ) {
    // We will let subclasses handle this computation
    return true;
  }

  /**
   * Adds a set of properties as a locale properties file for the specified Domain ID
   *
   * @param domainId
   *          the domain ID for which this properties file will be added
   * @param locale
   *          the locale for which this properties file will be added
   * @param properties
   *          the properties to be added
   */
  public void addLocalizationFile( final String domainId, final String locale, final Properties properties )
    throws DomainStorageException {
    // This is safe since ByteArray streams don't have to be closed
    if ( null != properties ) {
      try {
        final OutputStream out = new ByteArrayOutputStream();
        properties.store( out, null );
        addLocalizationFile( domainId, locale, new ByteArrayInputStream( out.toString().getBytes() ), true );
      } catch ( IOException e ) {
        throw new DomainStorageException( messages.getErrorString(
            "PentahoMetadataDomainRepository.ERROR_0008_ERROR_IN_REPOSITORY", e.getLocalizedMessage() ), e );
      }
    }
  }

  @Override
  public void addLocalizationFile( final String domainId, final String locale, final InputStream inputStream,
      final boolean overwrite ) throws DomainStorageException {
    logger.debug( "addLocalizationFile(" + domainId + ", " + locale + ", inputStream)" );
    if ( null != inputStream ) {
      if ( StringUtils.isEmpty( domainId ) || StringUtils.isEmpty( locale ) ) {
        throw new IllegalArgumentException( messages.getErrorString(
            "PentahoMetadataDomainRepository.ERROR_0004_DOMAIN_ID_INVALID", domainId ) );
      }

      synchronized ( metadataMapping ) {
        // Check for duplicates
        final RepositoryFile localeFile = metadataMapping.getLocaleFile( domainId, locale );
        if ( !overwrite && localeFile != null ) {
          throw new DomainStorageException( messages.getErrorString(
              "PentahoMetadataDomainRepository.ERROR_0009_LOCALE_ALREADY_EXISTS", domainId, locale ), null );
        }

        final SimpleRepositoryFileData data =
            new SimpleRepositoryFileData( inputStream, DEFAULT_ENCODING, LOCALE_MIME_TYPE );
        if ( localeFile == null ) {
          final RepositoryFile newLocaleFile = createUniqueFile( domainId, locale, data );
          metadataMapping.addLocale( domainId, locale, newLocaleFile );
        } else {
          repository.updateFile( localeFile, data, null );
        }
      }

      // This invalidates any cached information
      flushDomains();
    }
  }

  protected RepositoryFile getMetadataDir() {
    final String metadataDirName = PentahoMetadataDomainRepositoryInfo.getMetadataFolderPath();
    return repository.getFile( metadataDirName );
  }

  protected void loadLocaleStrings( final String domainId, final Domain domain ) {
    final Map<String, RepositoryFile> localeFiles = metadataMapping.getLocaleFiles( domainId );
    if ( localeFiles != null ) {
      for ( final String locale : localeFiles.keySet() ) {
        final RepositoryFile localeFile = localeFiles.get( locale );
        final Properties properties = loadProperties( localeFile );
        logger.trace( "\tLoading properties [" + domain + " : " + locale + "]" );
        localizationUtil.importLocalizedProperties( domain, properties, locale );
      }
    }
  }

  protected Properties loadProperties( final RepositoryFile bundle ) {
    try {
      Properties properties = null;
      final SimpleRepositoryFileData bundleData =
          repository.getDataForRead( bundle.getId(), SimpleRepositoryFileData.class );
      if ( bundleData != null ) {
        properties = new Properties();
        properties.load( bundleData.getStream() );
      } else {
        logger.warn( "Could not load properties from repository file: " + bundle.getName() );
      }
      return properties;
    } catch ( IOException e ) {
      throw new UnifiedRepositoryException( messages.getErrorString(
          "PentahoMetadataDomainRepository.ERROR_0008_ERROR_IN_REPOSITORY", e.getLocalizedMessage() ), e );
    }
  }

  /**
   * Creates a new repository file (with the supplied data) and applies the proper metadata to this file.
   *
   * @param domainId
   *          the Domain id associated with this file
   * @param locale
   *          the locale associated with this file (or null for a domain file)
   * @param data
   *          the data to put in the file
   * @return the repository file created
   */
  protected RepositoryFile createUniqueFile( final String domainId, final String locale,
      final SimpleRepositoryFileData data ) {
    // Generate a "unique" filename
    final String filename = UUID.randomUUID().toString();

    // Create the new file
    final RepositoryFile file =
        repository.createFile( getMetadataDir().getId(), new RepositoryFile.Builder( filename ).build(), data, null );

    // Add metadata to the file
    final Map<String, Serializable> metadataMap = new HashMap<String, Serializable>();
    metadataMap.put( PROPERTY_NAME_DOMAIN_ID, domainId );
    if ( StringUtils.isEmpty( locale ) ) {
      // This is a domain file
      metadataMap.put( PROPERTY_NAME_TYPE, TYPE_DOMAIN );
    } else {
      // This is a locale property file
      metadataMap.put( PROPERTY_NAME_TYPE, TYPE_LOCALE );
      metadataMap.put( PROPERTY_NAME_LOCALE, locale );
    }

    // Update the metadata
    repository.setFileMetadata( file.getId(), metadataMap );
    return file;
  }

  protected IUnifiedRepository getRepository() {
    return repository;
  }

  protected XmiParser getXmiParser() {
    return xmiParser;
  }

  protected RepositoryUtils getRepositoryUtils() {
    return repositoryUtils;
  }

  protected LocalizationUtil getLocalizationUtil() {
    return localizationUtil;
  }

  protected void setRepository( final IUnifiedRepository repository ) {
    this.repository = repository;
  }

  protected void setXmiParser( final XmiParser xmiParser ) {
    this.xmiParser = ( xmiParser != null ? xmiParser : new XmiParser() );
  }

  protected void setRepositoryUtils( final RepositoryUtils repositoryUtils ) {
    this.repositoryUtils = ( repositoryUtils != null ? repositoryUtils : new RepositoryUtils( repository ) );
  }

  protected void setLocalizationUtil( final LocalizationUtil localizationUtil ) {
    this.localizationUtil = ( localizationUtil != null ? localizationUtil : new LocalizationUtil() );
  }

  protected String toString( final RepositoryFile file ) {
    try {
      final Map<String, Serializable> fileMetadata = repository.getFileMetadata( file.getId() );
      return "[type=" + fileMetadata.get( PROPERTY_NAME_TYPE ) + " : domain="
          + fileMetadata.get( PROPERTY_NAME_DOMAIN_ID ) + " : locale=" + fileMetadata.get( PROPERTY_NAME_LOCALE )
          + " : filename=" + file.getName() + "]";
    } catch ( Throwable ignore ) {
      //ignore
    }
    return "null";
  }

  /**
   * Accesses the metadata mapping (with 1 retry) to find the metadata file for the specified domainId
   */
  protected RepositoryFile getMetadataRepositoryFile( final String domainId ) {
    RepositoryFile domainFile = metadataMapping.getDomainFile( domainId );
    if ( null == domainFile ) {
      reloadDomains();
      domainFile = metadataMapping.getDomainFile( domainId );
    }
    return domainFile;
  }

  /**
   * Returns the MatadataInformationMap for the specified IUnifiedRepository
   *
   * @param repository
   *          the repository for which a map is specified
   * @return the MatadataInformationMap for the repository
   */
  private static synchronized PentahoMetadataInformationMap getMetadataMapping( final IUnifiedRepository repository ) {
    PentahoMetadataInformationMap metaMap = metaMapStore.get( repository );
    if ( null == metaMap ) {
      metaMap = new PentahoMetadataInformationMap();
      metaMapStore.put( repository, metaMap );
    }
    return metaMap;
  }
}
TOP

Related Classes of org.pentaho.platform.plugin.services.metadata.PentahoMetadataDomainRepository

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.