com.pentaho.repository.importexport.StreamToTransNodeConverter.java Source code

Java tutorial

Introduction

Here is the source code for com.pentaho.repository.importexport.StreamToTransNodeConverter.java

Source

/*!
 * Copyright 2010 - 2016 Pentaho Corporation.  All rights reserved.
 *
 * Licensed 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 com.pentaho.repository.importexport;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.di.cluster.ClusterSchema;
import org.pentaho.di.cluster.SlaveServer;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.extension.ExtensionPointHandler;
import org.pentaho.di.core.extension.KettleExtensionPoint;
import org.pentaho.di.core.logging.LogChannel;
import org.pentaho.di.partition.PartitionSchema;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.repository.RepositoryElementInterface;
import org.pentaho.di.repository.StringObjectId;
import org.pentaho.di.repository.pur.TransDelegate;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.platform.api.repository2.unified.Converter;
import org.pentaho.platform.api.repository2.unified.IRepositoryFileData;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.data.node.NodeRepositoryFileData;
import org.pentaho.platform.api.repository2.unified.data.simple.SimpleRepositoryFileData;
import org.w3c.dom.Document;

/**
 * Converts stream of binary or character data.
 * 
 * @author rmansoor
 */
public class StreamToTransNodeConverter implements Converter {
    IUnifiedRepository unifiedRepository;

    private static final Log logger = LogFactory.getLog(StreamToTransNodeConverter.class);

    public StreamToTransNodeConverter(IUnifiedRepository unifiedRepository) {
        this.unifiedRepository = unifiedRepository;
    }

    public InputStream convert(final IRepositoryFileData data) {
        throw new UnsupportedOperationException();
    }

    /**
     * 
     * @param fileId
     * @return
     */
    public InputStream convert(final Serializable fileId) {
        try {
            // this will change in the future if PDI no longer has its
            // own repository. For now, get the reference
            if (fileId != null) {
                Repository repository = connectToRepository();
                RepositoryFile file = unifiedRepository.getFileById(fileId);
                if (file != null) {
                    try {
                        TransMeta transMeta = repository.loadTransformation(new StringObjectId(fileId.toString()),
                                null);
                        if (transMeta != null) {
                            Set<String> privateDatabases = transMeta.getPrivateDatabases();
                            if (privateDatabases != null) {
                                // keep only private transformation databases
                                for (Iterator<DatabaseMeta> it = transMeta.getDatabases().iterator(); it
                                        .hasNext();) {
                                    String databaseName = it.next().getName();
                                    if (!privateDatabases.contains(databaseName)) {
                                        it.remove();
                                    }
                                }
                            }
                            return new ByteArrayInputStream(transMeta.getXML().getBytes());
                        }
                    } catch (KettleException e) {
                        logger.error(e);
                        // file is there and may be legacy, attempt simple export
                        SimpleRepositoryFileData fileData = unifiedRepository.getDataForRead(fileId,
                                SimpleRepositoryFileData.class);
                        if (fileData != null) {
                            logger.warn("Reading as legacy CE tranformation " + file.getName() + ".");
                            return fileData.getInputStream();
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return null;
    }

    // package-local visibility for testing purposes
    Repository connectToRepository() throws KettleException {
        return PDIImportUtil.connectToRepository(null);
    }

    public IRepositoryFileData convert(final InputStream inputStream, final String charset, final String mimeType) {
        try {
            long size = inputStream.available();
            TransMeta transMeta = new TransMeta();
            Repository repository = connectToRepository();
            Document doc = PDIImportUtil.loadXMLFrom(inputStream);
            transMeta.loadXML(doc.getDocumentElement(), repository, false);
            TransDelegate delegate = new TransDelegate(repository, this.unifiedRepository);
            saveSharedObjects(repository, transMeta);
            return new NodeRepositoryFileData(delegate.elementToDataNode(transMeta), size);
        } catch (Exception e) {
            logger.error(e);
            return null;
        }
    }

    private void saveSharedObjects(final Repository repo, final RepositoryElementInterface element)
            throws KettleException {
        TransMeta transMeta = (TransMeta) element;
        // First store the databases and other depending objects in the transformation.
        List<String> databaseNames = Arrays.asList(repo.getDatabaseNames(true));

        int dbIndex = 0;
        boolean updateMeta = Boolean.FALSE;

        List<Integer> transMetaDatabasesToUpdate = new ArrayList<Integer>();

        for (DatabaseMeta databaseMeta : transMeta.getDatabases()) {
            if (!databaseNames.contains(databaseMeta.getName())) {
                if (databaseMeta.getObjectId() == null || !StringUtils.isEmpty(databaseMeta.getHostname())) {
                    repo.save(databaseMeta, null, null);
                }
            } else if (databaseMeta.getObjectId() == null) {
                // add this to the list to update object Ids later
                transMetaDatabasesToUpdate.add(dbIndex);
                updateMeta = Boolean.TRUE;
            }

            dbIndex++;
        }

        if (updateMeta) {
            // make sure to update object ids in the transmeta db collection
            for (Integer databaseMetaIndex : transMetaDatabasesToUpdate) {
                transMeta.getDatabase(databaseMetaIndex)
                        .setObjectId(repo.getDatabaseID(transMeta.getDatabase(databaseMetaIndex).getName()));
            }
        }

        // Store the slave servers...
        //
        for (SlaveServer slaveServer : transMeta.getSlaveServers()) {
            if (slaveServer.hasChanged() || slaveServer.getObjectId() == null) {
                repo.save(slaveServer, null, null);
            }
        }

        // Store the cluster schemas
        //
        for (ClusterSchema clusterSchema : transMeta.getClusterSchemas()) {
            if (clusterSchema.hasChanged() || clusterSchema.getObjectId() == null) {
                repo.save(clusterSchema, null, null);
            }
        }

        // Save the partition schemas
        //
        for (PartitionSchema partitionSchema : transMeta.getPartitionSchemas()) {
            if (partitionSchema.hasChanged() || partitionSchema.getObjectId() == null) {
                repo.save(partitionSchema, null, null);
            }
        }
    }

    public void convertPostRepoSave(RepositoryFile repositoryFile) {
        if (repositoryFile != null) {
            try {
                Repository repo = connectToRepository();
                if (repo != null) {
                    TransMeta transMeta = repo
                            .loadTransformation(new StringObjectId(repositoryFile.getId().toString()), null);
                    ExtensionPointHandler.callExtensionPoint(new LogChannel(this),
                            KettleExtensionPoint.TransImportAfterSaveToRepo.id, transMeta);
                }
            } catch (Exception e) {
                logger.error(KettleExtensionPoint.TransImportAfterSaveToRepo.id, e);
            }
        }
    }
}