/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.rim.ejde.internal.core.IConstants;
import net.rim.ide.JavaParser;
import net.rim.ide.Project;
import net.rim.sdk.rc.ConvertUtil;
import net.rim.sdk.rc.ResourceCollection;
import net.rim.sdk.rc.parser.ResourceHeaderParser;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.JavaModel;
import org.eclipse.osgi.util.NLS;
/**
* A utility class to construct/retrieve package informations.
*
* @author Raj Gunaratnam
* @since 11 December, 08
*/
public class PackageUtils implements net.rim.ejde.internal.core.IConstants {
private static final Logger _logger = Logger.getLogger( PackageUtils.class );
/**
* Get the package name of the given <code>rrhFile</code>.
* <p>
* The returned package is in <code>com/rim/test</code> format.
* </p>
*
* @param rrhFile
* @return packageId String or <code>null</code> if the given file is null or the given file is not a rrh file
* @throws CoreException
*/
public static String getRRHPackageString( File rrhFile ) throws CoreException {
String packageName = getRRHPackageID( rrhFile );
if( !StringUtils.isBlank( packageName ) ) {
packageName = convertPkgIDToString( packageName );
}
return packageName;
}
/**
* Get the file name of corresponding rrh file for the given <code>rrcFile</code>.
*
* @param rrcFile
* @return rrhFile
*/
public static File getCorrespondingRRHFile( File rrcFile ) {
if( rrcFile == null ) {
return null;
}
IPath rrcPath = new Path( rrcFile.getPath() );
String extension = rrcPath.getFileExtension();
if( ( extension == null ) || !extension.equalsIgnoreCase( RRC_FILE_EXTENSION ) ) {
return null;
}
String fileName = rrcFile.getName();
if( fileName.contains( "_" ) ) {
fileName = fileName.substring( 0, fileName.indexOf( '_' ) );
} else {
fileName = fileName.substring( 0, fileName.indexOf( DOT_CHAR ) );
}
fileName += RRH_FILE_EXTENSION_WITH_DOT;
IPath rrhPath = rrcPath.removeLastSegments( 1 );
rrhPath = rrhPath.append( fileName );
return rrhPath.toFile();
}
/**
* Get the package string of the given <code>rrcFile</code>.
* <p>
* The returned package is in <code>com/rim/test</code> format.
* </p>
*
* @param rrcFile
* File
* @return packageId String or <code>null</code> if the given file is null or the given file is not a rrc file
* @throws CoreException
*/
public static String getRRCPackageString( File rrcFile ) throws CoreException {
String packageId;
packageId = getRRCPackageID( rrcFile );
if( !StringUtils.isBlank( packageId ) ) {
packageId = convertPkgIDToString( packageId );
}
return packageId;
}
/**
* Get the package id of the given <code>rrcFile</code>.
* <p>
* The returned package is in <code>com.rim.test</code> format.
* </p>
*
* @param rrcFile
* File
* @return packageId String or <code>null</code> if the given file is null or the given file is not a rrc file
* @throws CoreException
*/
public static String getRRCPackageID( File rrcFile ) throws CoreException {
if( rrcFile == null ) {
return null;
}
if( !rrcFile.getName().endsWith( RRC_FILE_EXTENSION_WITH_DOT ) ) {
return null;
}
String packageId = null;
File rrhFile = getCorrespondingRRHFile( rrcFile );
if( rrhFile != null ) {
try {
packageId = getRRHPackageID( rrhFile );
} catch( CoreException e ) {
throw new CoreException( StatusFactory.createErrorStatus( NLS.bind(
Messages.PackageUtils_RELATED_RRH_FILE_ERROR_MESSAGE, rrcFile.getPath() ) ) );
}
}
return packageId;
}
/**
* Get the package id of the given <code>rrhFile</code>.
* <p>
* The returned package is in <code>com.rim.test</code> format.
* </p>
*
* @param rrhFile
* File
* @return packageId String or <code>null</code> if the given file is null or the given file is not a rrh file
* @throws CoreException
*/
public static String getRRHPackageID( File rrhFile ) throws CoreException {
if( rrhFile == null ) {
return null;
}
if( !rrhFile.getName().endsWith( RRH_FILE_EXTENSION_WITH_DOT ) ) {
return null;
}
if( !rrhFile.exists() ) {
throw new CoreException( StatusFactory.createErrorStatus( NLS.bind( Messages.PackageUtils_RRH_FILE_NOT_EXIST,
rrhFile.toString() ) ) );
}
String fileStringPath = rrhFile.getPath();
ResourceCollection collection = new ResourceCollection( fileStringPath.substring( 0, fileStringPath.length() - 4 ) );
ResourceHeaderParser parser = null;
String packageName = null;
try {
parser = new ResourceHeaderParser( fileStringPath, collection );
parser.read();
} catch( IOException e ) {
_logger.error( NLS.bind( Messages.PackageUtils_PACKAGE_ID_ERROR_MSG, rrhFile.toString() ) );
throw new CoreException( StatusFactory.createErrorStatus(
NLS.bind( Messages.PackageUtils_PACKAGE_ID_ERROR_MSG, rrhFile.toString() ), e ) );
}
packageName = collection.getPackage();
return packageName;
}
/**
* Get the package string of the given <code>imgFile</code> within given <code>eclipseProject</code>. This method will
* calculate package id based on the JDP file location. This method can be used for any non java, non rrh and non rrc files
* package calculation.
* <p>
* The returned package is in <code>com/rim/test</code> format.
* </P>
*
* @param file
* File
* @return packageId String
*/
static public String buildGenaralFilePackageString( File file, Project legacyProject ) {
IPath filePath = null;
String pathAlias = EMPTY_STRING;
if( ( file == null ) ) {
throw new IllegalArgumentException(
NLS.bind( Messages.PackageUtils_UNDEFINED_FILE_ERROR_MSG, IConstants.EMPTY_STRING ) );
}
if( file.getName().endsWith( JAVA_EXTENSION_WITH_DOT ) || file.getName().endsWith( RRC_FILE_EXTENSION_WITH_DOT )
|| file.getName().endsWith( RRH_FILE_EXTENSION_WITH_DOT ) ) {
throw new IllegalArgumentException( "This method doesn't process java/rrh/rrc files!" );
}
filePath = new Path( file.getPath() );
if( legacyProject != null ) {
IPath bbwkspath = ( new Path( legacyProject.getWorkspace().getFile().toString() ) ).removeLastSegments( 1 );
IPath bbprjpath = ( new Path( legacyProject.getFile().toString() ) ).removeLastSegments( 1 );
// remove the file name segment
IPath resolvedPath = resolvePathForFile( filePath, bbprjpath, bbwkspath ).removeLastSegments( 1 );
List< String > sources = ImportUtils.getSources( legacyProject );
String firstSegment = resolvedPath.segment( 0 );
if( sources.contains( firstSegment ) ) {
resolvedPath = resolvedPath.removeFirstSegments( 1 );
}
pathAlias = resolvedPath.toString();
}
return pathAlias;// com/rim/test
}
/**
* Deresolves a file path 1st referred to a project path, then to a workspace path or flatten if completely outside
*
* @param file
* @param projectPath
* @param workspacePath
* @return
*/
public static IPath resolvePathForFile( IPath filePath, IPath projectPath, IPath workspacePath ) {
IPath deresolvedPath = deResolve( filePath, projectPath );
if( deresolvedPath.isAbsolute() || DOUBLE_DOTS.equals( deresolvedPath.segment( 0 ) ) ) {
deresolvedPath = deResolve( filePath, workspacePath );
if( deresolvedPath.isAbsolute() || DOUBLE_DOTS.equals( deresolvedPath.segment( 0 ) ) ) {
deresolvedPath = new Path( filePath.lastSegment() );
}
}
return deresolvedPath;
}
/**
* Return the absolute path of the given entry.
*
* @param currentEntry
* @return the absolute path of the give entry. Return <code>null<code> if the entry can not be found.
*/
public static IPath getAbsolutePath( IClasspathEntry currentEntry ) {
if( currentEntry == null ) {
return null;
}
if( currentEntry.getEntryKind() != IClasspathEntry.CPE_LIBRARY ) {
return currentEntry.getPath();
}
IPath absolutePath = null;
IPath path = currentEntry.getPath();
Object target = JavaModel.getTarget( path, true );
if( target instanceof IResource ) {
// if the target was found inside workspace
IResource resource = (IResource) target;
absolutePath = resource.getLocation();
} else if( target instanceof File ) {
// if the target was found outside of the workspace
absolutePath = new Path( ( (File) target ).getAbsolutePath() );
}
return absolutePath;
}
/**
* @deprecatated Use {@link getAbsolutePath(IClasspathEntry)} instead
*/
public static IPath getAbsoluteEntryPath( IClasspathEntry currentEntry ) {
return getAbsolutePath( currentEntry );
}
/**
* De-resolves a path vs a base path Example: path --> C:\workspace\myProject\com\rim\test\a.JPG base -->
* C:\workspace\myProject\P1.jdp return path --> com/rim/test/a.JPG -- relative to JDP
*
* @param path
* IPath
* @param base
* IPath
* @return path IPath
*/
public static IPath deResolve( IPath path, IPath base ) {
IPath modfiedBase = base;
if( modfiedBase.toFile().isFile() ) {
modfiedBase = modfiedBase.removeLastSegments( 1 );
}
int mn = modfiedBase.matchingFirstSegments( path );
if( mn > 0 ) {
IPath dpath = path.setDevice( EMPTY_STRING ).removeFirstSegments( mn );
int nj = modfiedBase.segmentCount() - mn;
// TODO: Try using forward slash as a path separator in Windows
String str = DOUBLE_DOTS + File.separator;
IPath tempPath = new Path( str );
for( int i = 0; i < nj; i++ ) {
dpath = tempPath.append( dpath );
}
return dpath;
}
return path; // com/rim/test/a.JPG
}
/**
* Gets all the source folders of the given <code>iJavaProject</code>.
*
* @param iJavaProject
* @return
*/
public static ArrayList< IContainer > getAllSrcFolders( IJavaProject iJavaProject ) {
ArrayList< IContainer > result = new ArrayList< IContainer >();
IProject iProject = iJavaProject.getProject();
IClasspathEntry[] classPathEntries = null;
IFolder srcFolder = null;
IPath srcFolderPath = null;
IPath relativeSrcFolderPath = null;
try {
classPathEntries = iJavaProject.getRawClasspath();
for( IClasspathEntry classPathEntry : classPathEntries ) {
if( classPathEntry.getEntryKind() != IClasspathEntry.CPE_SOURCE ) {
continue;
}
srcFolderPath = classPathEntry.getPath();
if( srcFolderPath.segment( 0 ).equals( iProject.getName() ) ) {
// remove the project name from the path
relativeSrcFolderPath = srcFolderPath.removeFirstSegments( 1 );
}
if( relativeSrcFolderPath == null || relativeSrcFolderPath.isEmpty() ) {
result.add( iProject );
} else {
srcFolder = iProject.getFolder( relativeSrcFolderPath );
if( srcFolder.exists() ) {
result.add( srcFolder );
}
}
}
} catch( Throwable e ) {
_logger.error( e.getMessage(), e );
}
return result;
}
/**
* This method will retrieves the list of non derived source folders of the given <code>iJavaProject</code>.
*
* @param iJavaProject
* IJavaProject
* @return result ArrayList<IFolder>
*/
public static ArrayList< IContainer > getNonDerivedSrcFolders( IJavaProject iJavaProject ) {
ArrayList< IContainer > result = getAllSrcFolders( iJavaProject );
ArrayList< IContainer > newResult = new ArrayList< IContainer >();
for( IContainer container : result ) {
if( !container.isDerived() ) {
newResult.add( container );
}
}
return newResult;
}
/**
* This method will retrieves the 1st source-folder other than src if multiple
*
* @param iJavaProject
* @return <IFolder> srcFolder or null if no source-folders
*/
public static IContainer getSrcFolderForNonPackage( IJavaProject iJavaProject ) {
ArrayList< IContainer > srcFolders = getNonDerivedSrcFolders( iJavaProject );
for( IContainer srcFolder : srcFolders ) {
if( "src".equals( srcFolder.getName() ) && ( srcFolders.size() > 1 ) ) {
continue;
}
return srcFolder;
}
return null;
}
/**
* This method will return true if the given resource is under any source folders
*
* @param resource
* IResource
* @return found Boolean
*/
public static boolean isUnderSrcFolder( IResource resource ) {
boolean found = false;
IPath path = resource.getFullPath();
IProject iProject = resource.getProject();
IJavaProject iJavaProject = JavaCore.create( iProject );
ArrayList< IContainer > srcc = PackageUtils.getAllSrcFolders( iJavaProject );
for( IContainer srcFolder : srcc ) {
IPath p = srcFolder.getFullPath();
if( p.isPrefixOf( path ) || path.isPrefixOf( p ) ) {
found = true;
break;
}
}
return found;
}
/**
* This method will return true if the resource represented by the given <code>path</code> is under/linked to any source
* folders of the <code>eclipseJavaProject</code>.
*
* @param eclipseJavaProject
* IJavaProject
* @param path
* IPath
*
* @return
*/
public static boolean isUnderSrcFolder( IJavaProject eclipseJavaProject, IPath path ) {
List< IContainer > srcc = PackageUtils.getAllSrcFolders( eclipseJavaProject );
IPath p;
for( IContainer srcFolder : srcc ) {
p = srcFolder.getLocation();
if( p.isPrefixOf( path ) ) {
return true;
} else {
// continue to check if the resource represented by the path is linked to the project
FileSearchVisitor visitor = new FileSearchVisitor( path );
try {
srcFolder.accept( visitor );
} catch( CoreException e ) {
_logger.error( e.getMessage() );
return false;
}
if( visitor.found() ) {
return true;
}
}
}
return false;
}
static private class FileSearchVisitor implements IResourceVisitor {
IPath _path;
boolean _found;
public FileSearchVisitor( IPath path ) {
_path = path;
_found = false;
}
@Override
public boolean visit( IResource resource ) throws CoreException {
if( _found ) {
return false;
}
if( !( resource instanceof IFile ) ) {
return true;
}
if( resource.getLocation().equals( _path ) ) {
_found = true;
}
return false;
}
public boolean found() {
return _found;
}
}
/**
* Get the project relative path of the resource represented by the given <code>filePath</code>. The <code>filePath</code> is
* a path which contains package and file name.
*
* @param javaProject
* @param filePath
* @return Project relative path which contains source folder/package/filename, e.g. src/net/rim/api/a.java.
* <p>
* or <code>null</code> if the filepath does not exist in the project.
*/
public static IPath getProjectRelativePath( IJavaProject javaProject, IPath filePath ) {
List< IContainer > srcc = PackageUtils.getNonDerivedSrcFolders( javaProject );
IPath p;
IFile iFile;
for( IContainer srcFolder : srcc ) {
p = new Path( srcFolder.getName() ).append( filePath );
iFile = javaProject.getProject().getFile( p );
if( iFile.exists() ) {
return p;
}
}
return null;
}
/**
* This method will return the source folder in which the given <code>resource</code> is located.
*
* @param resource
* IResource
* @return the source folder in which the given <code>resource</code> is located or <code>null</code> if the given
* <code>resource</code> is not located in any source folder
*/
public static IContainer getSrcFolder( IResource resource ) {
IPath path = resource.getFullPath();
IProject iProject = resource.getProject();
IJavaProject iJavaProject = JavaCore.create( iProject );
ArrayList< IContainer > srcFolders = getNonDerivedSrcFolders( iJavaProject );
for( IContainer srcFolder : srcFolders ) {
IPath p = srcFolder.getFullPath();
if( p.isPrefixOf( path ) ) {
return srcFolder;
}
}
return null;
}
/**
* Get package string for java file in <code>com/rim/test</code> format.
*
* @param file
* File
* @return packageId String
*/
public static String getJavaFilePackageString( File file ) {
String packageId = getJavaFilePackageID( file );
if( !StringUtils.isBlank( packageId ) ) {
packageId = convertPkgIDToString( packageId );
}
return packageId; // com/rim/test
}
/**
* Get package id for java file in com.rim.test format
*
* @param file
* File
* @return packageId String
*/
public static String getJavaFilePackageID( File file ) {
String packageId = EMPTY_STRING;
if( file == null ) {
return EMPTY_STRING;
}
try {
FileReader fileReader = new FileReader( file );
JavaParser parser = new JavaParser( file, fileReader, true );
packageId = parser.getPackage();
try {
fileReader.close();
} catch( IOException ioe ) {
_logger.error( ioe );
}
return packageId; // com.rim.test
} catch( FileNotFoundException fnfe ) {
return EMPTY_STRING;
}
}
/**
* Whether the given filename has a BB source type extension
*
* @param filename
* @return
*/
public static boolean hasSourceExtension( String filename ) {
String filename_ = filename.toLowerCase();
return filename_.endsWith( JAVA_EXTENSION_WITH_DOT ) || filename_.endsWith( RRH_FILE_EXTENSION_WITH_DOT )
|| filename_.endsWith( RRC_FILE_EXTENSION_WITH_DOT );
}
/**
* Whether is a java file by extension
*
* @param filename
* @return
*/
public static boolean hasJavaExtension( String filename ) {
return filename.toLowerCase().endsWith( JAVA_EXTENSION_WITH_DOT );
}
/**
* Whether is a rrh file by extension
*
* @param filename
* @return
*/
public static boolean hasRRHExtension( String filename ) {
return filename.toLowerCase().endsWith( RRH_FILE_EXTENSION_WITH_DOT );
}
/**
* Whether is a rrc file by extension
*
* @param filename
* @return
*/
public static boolean hasRRCExtension( String filename ) {
return filename.toLowerCase().endsWith( RRC_FILE_EXTENSION_WITH_DOT );
}
/**
* A common method to get a relative file path w\ package string for given <code>File</code>.
* <p>
* The returned path is in <code>com/rim/test</code> format.
* </p>
*
* @param file
* @param legacyProject
* @return package string
* @throws IOException
*/
public static String getFilePackageString( File file, Project legacyProject ) throws CoreException {
String packageString;
String fileName = file.getName();
if( fileName.endsWith( JAVA_EXTENSION_WITH_DOT ) ) {
packageString = getJavaFilePackageString( file );
} else if( fileName.endsWith( RRH_FILE_EXTENSION_WITH_DOT ) ) {
packageString = getRRHPackageString( file );
} else if( fileName.endsWith( RRC_FILE_EXTENSION_WITH_DOT ) ) {
packageString = getRRCPackageString( file );
} else {
packageString = buildGenaralFilePackageString( file, legacyProject );
}
return packageString;
}
/**
* This method will convert the package name (com.rim.test) into package id (exclusion pattern) format (com/rim/test)
*
* @param packageID
* String
* @return result String
*/
public static String convertPkgIDToString( String packageID ) {
String result = packageID;
if( result == null ) {
return null;
}
result = packageID.replace( DOT_CHAR, File.separatorChar );
return result;// my/net/rim
}
/**
* This method will convert the package String (com/rim/test) into package id format (com.rim.test)
*
* @param packageString
* String
* @return result String
*/
public static String convertPkgStringToID( String packageString ) {
StringBuffer buf = new StringBuffer();
if( packageString == null ) {
return null;
}
IPath path = new Path( packageString );
for( int i = 0; i < path.segmentCount(); i++ ) {
if( i == 0 ) {
buf.append( path.segment( i ) );
} else {
buf.append( DOT_MARK + path.segment( i ) );
}
}
return buf.toString(); // com.rim.test
}
/**
* Compose the crb file name based on the given <code>rrcFileNem</code> and <code>packageID</code>. The given
* <code>rrcFileName</code> should not contain the file extension (.rrc).
*
* <p>
* If the given <code>rrcFile</code> is resource_en_US and the given <code>packageID</code> is "net.rim.test", the returned
* crb file name is <code>net.rim.test.resource�en_US.crb</code>.
* </p>
*
* @param rrcFileName
* @return
*/
public static String getCRBFileName( String rrcFileName, String packageID, boolean alt ) {
int index = rrcFileName.indexOf( "_" ); //$NON-NLS-1$
String crbFileName;
if( index > 0 ) {
String fileNameWithoutLocal = rrcFileName.substring( 0, index );
// get the locale string, e.g. en_us
String localeString = rrcFileName.substring( index + 1 );
localeString = ConvertUtil.localeValueOf( localeString ).toString().trim();
// resource_en_us --> resource�en_us
if( alt ) {
localeString = convertAltLocale( localeString );
}
crbFileName = fileNameWithoutLocal + String.valueOf( ConvertUtil.LOCALE_SEPARATOR ) + localeString;
} else {
crbFileName = rrcFileName + String.valueOf( ConvertUtil.LOCALE_SEPARATOR );
}
// append .crb extension
crbFileName += CRB_EXTENSION_WITH_DOT;
// add the package id
if( !StringUtils.isBlank( packageID ) ) {
crbFileName = packageID + DOT_CHAR + crbFileName;
}
return crbFileName;
}
private static String convertAltLocale( String localeString ) {
String altLocale = localeString;
if( localeString.startsWith( "iw" ) ) {
altLocale = "he" + localeString.substring( 2 );
} else if( localeString.startsWith( "in" ) ) {
altLocale = "id" + localeString.substring( 2 );
}
return altLocale;
}
public static void createFolder( IFolder folder ) throws CoreException {
if( !folder.exists() ) {
IContainer parent = folder.getParent();
if( parent instanceof IFolder ) {
createFolder( (IFolder) parent );
}
folder.create( true, true, new NullProgressMonitor() );
}
}
static public String parseFileForPackageId( File file ) {
if( ( null == file ) || file.isDirectory() || !file.exists() ) {
String msg = NLS.bind( Messages.PackageUtils_UNDEFINED_FILE_ERROR_MSG, IConstants.EMPTY_STRING );
_logger.error( msg );
throw new RuntimeException( msg );
}
String packageId = null, filePath = file.getAbsolutePath(), line, token;
BufferedReader bufferedReader = null;
StringTokenizer tokenizer;
try {
if( PackageUtils.hasRRHExtension( filePath ) || PackageUtils.hasRRCExtension( filePath )
|| PackageUtils.hasJavaExtension( filePath ) ) {
bufferedReader = new BufferedReader( new FileReader( file ) );
if( !bufferedReader.ready() ) {
throw new RuntimeException( NLS.bind( Messages.PackageUtils_EMPTY_FILE_ERROR_MSG, file.getPath() ) );
}
while( null != ( line = bufferedReader.readLine() ) ) {
// pull lines from file till find the one containing
// package definition
line = line.trim();
if( ( 0 < line.length() ) && // criterion to recognize a
// package declaration
line.startsWith( "package" ) ) {
while( !line.contains( IConstants.SEMICOLON_MARK ) ) {
line = line + bufferedReader.readLine();
}
tokenizer = new StringTokenizer( line );
while( tokenizer.hasMoreTokens() ) {
// pull the package tokens
token = tokenizer.nextToken();
if( !"package".equals( token ) ) {
if( token.contains( IConstants.SEMICOLON_MARK ) ) {
token = token.replaceAll( IConstants.SEMICOLON_MARK, IConstants.EMPTY_STRING );
}
packageId = StringUtils.isNotBlank( token ) ? token : IConstants.EMPTY_STRING;
break;
}// end pulling of eventual package tokens
}
}
if( null != packageId ) {
// file
break;
}
}
} else {
throw new RuntimeException( NLS.bind( Messages.PackageUtils_UNSUPPORTED_FILE_ERROR_MSG, file.getPath() ) );
}
} catch( Throwable t ) {
_logger.debug( t.getMessage(), t );
} finally {
if( null != bufferedReader ) {
try {
bufferedReader.close();
} catch( IOException e ) {
_logger.error( e.getMessage(), e );
}
}
}
return packageId;
}
}