/*! * 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.platform.plugin.services.importer; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.PropertyResourceBundle; import org.apache.commons.lang.StringUtils; import org.pentaho.platform.api.repository2.unified.IPlatformImportBundle; import org.pentaho.platform.api.mimetype.IPlatformMimeResolver; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.plugin.services.importexport.ExportFileNameEncoder; import org.pentaho.platform.plugin.services.importexport.ImportSession; import org.pentaho.platform.plugin.services.importexport.ImportSource.IRepositoryFileBundle; import org.pentaho.platform.repository.RepositoryFilenameUtils; /** * this class is used to handle .properties files that are XACTION or URL files that contain the metadata used for * localization. These files may contain additional information that will allow the properties file to be stored and * used by XACTION and URL as well as localize the title and description. * * @author tband /ezequiel / tkafalas * */ public class LocaleFilesProcessor { private static final String FILE_LOCALE_RESOLVER = "file.locale"; private static final String URL_DESCRIPTION = "url_description"; private static final String URL_NAME = "url_name"; private static final String DESCRIPTION = "description"; private static final String TITLE = "title"; private static final String NAME = "name"; private static final String PROPERTIES_EXT = ".properties"; private static final String LOCALE_EXT = ".locale"; private List<LocaleFileDescriptor> localeFiles; public LocaleFilesProcessor() { localeFiles = new ArrayList<LocaleFileDescriptor>(); } /** * * @param file * @param parentPath * @param bytes * @return false - means discard the file extension type * @throws IOException */ public boolean isLocaleFile( IRepositoryFileBundle file, String parentPath, byte[] bytes ) throws IOException { boolean isLocale = false; String fileName = file.getFile().getName(); String actualFilePath = file.getPath(); RepositoryFile localeRepositoryFile = file.getFile(); if ( ImportSession.getSession().getManifest() != null && ImportSession.getSession().getManifest().getManifestInformation().getManifestVersion() != null ) { fileName = ExportFileNameEncoder.decodeZipFileName( fileName ); actualFilePath = ExportFileNameEncoder.decodeZipFileName( actualFilePath ); localeRepositoryFile = new RepositoryFile.Builder( localeRepositoryFile ).name( ExportFileNameEncoder.decodeZipFileName( localeRepositoryFile.getName() ) ).build(); } int sourceVersion = 0; // 0 = Not a local file, 1 = 4.8 .properties file, 2= Sugar 5.0 .local file if ( fileName.endsWith( PROPERTIES_EXT ) ) { sourceVersion = 1; } else if ( fileName.endsWith( LOCALE_EXT ) ) { sourceVersion = 2; } if ( sourceVersion != 0 ) { InputStream inputStream = new ByteArrayInputStream( bytes ); Properties properties = loadProperties( inputStream ); String name = getProperty( properties, NAME, sourceVersion ); String title = getProperty( properties, TITLE, sourceVersion ); String description = getProperty( properties, DESCRIPTION, sourceVersion ); String url_name = getProperty( properties, URL_NAME, sourceVersion ); String url_description = getProperty( properties, URL_DESCRIPTION, sourceVersion ); if ( !StringUtils.isEmpty( url_name ) ) { name = url_name; } if ( !StringUtils.isEmpty( title ) ) { name = title; } description = !StringUtils.isEmpty( description ) ? description : ""; if ( !StringUtils.isEmpty( url_description ) ) { description = url_description; } if ( !StringUtils.isEmpty( name ) ) { String filePath = ( actualFilePath.equals( "/" ) || actualFilePath.equals( "\\" ) ) ? "" : actualFilePath; filePath = RepositoryFilenameUtils.concat( parentPath, filePath ); LocaleFileDescriptor localeFile = new LocaleFileDescriptor( name, description, filePath, localeRepositoryFile, inputStream ); localeFiles.add( localeFile ); /** * assumes that the properties file has additional localization attributes and should be imported */ if ( properties.size() <= 2 || sourceVersion == 2 ) { isLocale = true; } } } return isLocale; } private String getProperty( Properties properties, String propertyName, int sourceVersion ) { if ( sourceVersion == 1 ) { return properties.getProperty( propertyName ); } else { return properties.getProperty( "file." + propertyName ); } } public Properties loadProperties( InputStream inputStream ) throws IOException { assert inputStream != null; final Properties properties = new Properties(); final PropertyResourceBundle rb = new PropertyResourceBundle( inputStream ); final Enumeration<?> keyEnum = rb.getKeys(); while ( keyEnum.hasMoreElements() ) { final Object key = keyEnum.nextElement(); assert key != null; final String sKey = String.valueOf( key ); properties.put( sKey, rb.getObject( sKey ) ); } return properties; } public boolean createLocaleEntry( String filePath, String name, String title, String description, RepositoryFile file, InputStream is ) throws IOException { return createLocaleEntry( filePath, name, title, description, file, is, 2 ); } public boolean createLocaleEntry( String filePath, String name, String title, String description, RepositoryFile file, InputStream is, int sourceVersion ) throws IOException { boolean success = false; // need to spoof the locales to think this is the actual parent .prpt and not the meta.xml RepositoryFile.Builder rf = new RepositoryFile.Builder( name ); rf.path( filePath ); if ( !StringUtils.isEmpty( title ) ) { name = title; } if ( !StringUtils.isEmpty( name ) ) { LocaleFileDescriptor localeFile = new LocaleFileDescriptor( name, description, filePath, rf.build(), is ); localeFiles.add( localeFile ); success = true; } return success; } public void processLocaleFiles( IPlatformImporter importer ) throws PlatformImportException { RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder(); IPlatformMimeResolver mimeResolver = PentahoSystem.get( IPlatformMimeResolver.class ); String mimeType = mimeResolver.resolveMimeForFileName( FILE_LOCALE_RESOLVER ); for ( LocaleFileDescriptor localeFile : localeFiles ) { bundleBuilder.name( localeFile.getName() ); bundleBuilder.comment( localeFile.getDescription() ); bundleBuilder.path( localeFile.getPath() ); bundleBuilder.file( localeFile.getFile() ); bundleBuilder.input( localeFile.getInputStream() ); bundleBuilder.mime( mimeType ); IPlatformImportBundle platformImportBundle = bundleBuilder.build(); importer.importFile( platformImportBundle ); } } }