/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. 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 *******************************************************************************/ package org.ebayopensource.turmeric.eclipse.errorlibrary.properties.ui.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLDecoder; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.lang.StringUtils; import org.apache.xbean.classloader.JarFileClassLoader; import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.model.PropertiesSOAError; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.model.PropertiesSOAErrorDomain; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.model.PropertiesSOAErrorLibrary; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.providers.PropertiesSOAConstants; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.vo.ErrorObjectXMLParser; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.vo.SOAErrorBundleVO; import org.ebayopensource.turmeric.eclipse.errorlibrary.properties.vo.SOAErrorVO; import org.ebayopensource.turmeric.eclipse.errorlibrary.ui.model.ErrorParamModel; import org.ebayopensource.turmeric.eclipse.errorlibrary.views.ISOAErrLibrary; import org.ebayopensource.turmeric.eclipse.errorlibrary.views.ISOAError; import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem; import org.ebayopensource.turmeric.eclipse.resources.model.AssetInfo; import org.ebayopensource.turmeric.eclipse.utils.io.PropertiesFileUtil; import org.ebayopensource.turmeric.eclipse.utils.lang.StringUtil; import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil; 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.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.jdom.JDOMException; /** * The Class TurmericErrorLibraryUtils. * * @author yayu */ public final class TurmericErrorLibraryUtils { private static final MessageFormat errorPropsFormat = new MessageFormat(PropertiesSOAConstants.PROPS_FILE_DEFAULT_ERROR_PROPERTIES); /** * */ private TurmericErrorLibraryUtils() { super(); } /** * Gets the domain list props file. * * @param project the project * @return the domain list props file */ public static IFile getDomainListPropsFile(IProject project) { return project.getFile(PropertiesSOAConstants.FOLDER_ERROR_DOMAIN + "/" + project.getName() + "/" + PropertiesSOAConstants.PROPS_FILE_ERROR_LIBRARY_PROJECT); } /** * Gets the error props file. * * @param project the project * @param domainName the domain name * @return the error props file * @throws CoreException the core exception */ public static IFile getErrorPropsFile(IProject project, String domainName) throws CoreException { IFolder domainFolder = getErrorDomainFolder(project, domainName); return getErrorPropsFile(domainFolder); } /** * Gets the error props file. * * @param domainFolder the domain folder * @return the error props file * @throws CoreException the core exception */ public static IFile getErrorPropsFile(IFolder domainFolder) throws CoreException { IFile defaultFile = getErrorPropsFile(domainFolder, PropertiesSOAConstants.DEFAULT_LOCALE); IFile noSuffixFile = domainFolder.getFile(PropertiesSOAConstants.PROPS_FILE_NO_LOCALE); if (defaultFile.isAccessible()) { return defaultFile; } else if (noSuffixFile.isAccessible()) { return noSuffixFile; } else if (domainFolder.isAccessible()){ for (IResource res : domainFolder.members()) { if (res instanceof IFile) { final IFile file = (IFile)res; if (file.getName().startsWith("Errors_")) { return file; } } } } return null; } /** * Gets the error props file. * * @param project the project * @param domainName the domain name * @param locale the locale * @return the error props file */ public static IFile getErrorPropsFile(IProject project, String domainName, String locale) { IFolder domainFolder = getErrorDomainFolder(project, domainName); return getErrorPropsFile(domainFolder, locale); } /** * Gets the error props file. * * @param domainFolder the domain folder * @param locale the locale * @return the error props file */ public static IFile getErrorPropsFile(IFolder domainFolder, String locale) { String propsFilename = errorPropsFormat.format(new Object[]{locale}); return domainFolder.getFile(propsFilename); } /** * Gets the all error domains. * * @param project the project * @return the all error domains * @throws CoreException the core exception */ public static Collection<String> getAllErrorDomains(IProject project) throws CoreException { final Collection<String> domains = new ArrayList<String>(); if (project != null && project.isAccessible() == true) { IFolder domainParentFolder = project.getFolder(PropertiesSOAConstants.FOLDER_ERROR_DOMAIN); if (domainParentFolder.isAccessible() == false) { return domains; } for (IResource res : domainParentFolder.members()) { if (res instanceof IFolder) { final IFolder folder = (IFolder)res; if (folder.findMember( PropertiesSOAConstants.FILE_ERROR_DATA) != null) { domains.add(folder.getName()); } } } } return domains; } /** * Gets the error domain folder. * * @param project the project * @param errorDomainName the error domain name * @return the error domain folder */ public static IFolder getErrorDomainFolder(IProject project, String errorDomainName) { return project.getFolder(PropertiesSOAConstants.FOLDER_ERROR_DOMAIN).getFolder(errorDomainName); } /** * Load error library. * * @param assetInfo the asset info * @return the iSOA err library * @throws Exception the exception */ public static ISOAErrLibrary loadErrorLibrary(AssetInfo assetInfo) throws Exception { ISOAErrLibrary result = null; final IProject project = WorkspaceUtil.getProject(assetInfo.getName()); if (project.isAccessible()) { PropertiesSOAErrorLibrary errLib = new PropertiesSOAErrorLibrary(); errLib.setName(assetInfo.getName()); errLib.setVersion(assetInfo.getVersion()); for (SOAErrorBundleVO bundle : ErrorObjectXMLParser.getErrorBundle(project)){ if (bundle != null) { PropertiesSOAErrorDomain domain = new PropertiesSOAErrorDomain(); domain.setLibrary(errLib); domain.setName(bundle.getDomain()); domain.setOrganization(bundle.getOrganization()); domain.setVersion(bundle.getVersion()); domain.setPackageName(bundle.getPackageName()); errLib.addErrorDomain(domain); //load error property file IFile errorPropFile = getErrorPropsFile(project, domain.getName()); Properties errorProperties = new Properties(); InputStream input = null; if (errorPropFile != null && errorPropFile.isAccessible()) { try { input = errorPropFile.getContents(); errorProperties.load(input); } finally { IOUtils.closeQuietly(input); } } for (SOAErrorVO vo : bundle.getList().getErrors()) { PropertiesSOAError err = new PropertiesSOAError(); err.setCategory(vo.getCategory()); err.setDomain(domain); err.setId(String.valueOf(vo.getId())); err.setName(vo.getName()); err.setSeverity(vo.getSeverity()); err.setSubDomain(vo.getSubdomain()); err.setMessage(errorProperties.getProperty(err.getName() + "." + PropertiesSOAConstants.PROPS_KEY_MESSAGE )); err.setResolution(errorProperties.getProperty(err.getName() + "." + PropertiesSOAConstants.PROPS_KEY_RESOLUTION)); domain.addError(err); } } } result = errLib; } else { result = loadErrorLibraryFromJar(assetInfo); } return result; } private static ISOAErrLibrary loadErrorLibraryFromJar(AssetInfo assetInfo) throws Exception { String assetLocation = GlobalRepositorySystem.instanceOf().getActiveRepositorySystem() .getAssetRegistry().getAssetLocation(assetInfo); String defaultErrorPropertyName = StringUtil.formatString( PropertiesSOAConstants.PROPS_FILE_DEFAULT_ERROR_PROPERTIES, PropertiesSOAConstants.DEFAULT_LOCALE); if (assetLocation != null) { File file = new File(assetLocation); if (file.canRead() == false) return null; URL url = file.toURI().toURL(); JarFileClassLoader classLoader = null; InputStream ins = null; String vmFileEncoding = System.getProperty("file.encoding"); try { URL decodedUrl = new URL(URLDecoder.decode(url.toString(), vmFileEncoding)); classLoader = new JarFileClassLoader("ErrorLibJarFileLoader", new URL[]{decodedUrl}); String filePath = PropertiesSOAConstants.FOLDER_ERROR_DOMAIN_IN_JAR + "/" + assetInfo.getName() + "/" + PropertiesSOAConstants.PROPS_FILE_ERROR_LIBRARY_PROJECT; URL domainListFile = classLoader.findResource(filePath); if (domainListFile == null) return null; ins = domainListFile.openStream(); Properties props = new Properties(); props.load(ins); PropertiesSOAErrorLibrary errLib = new PropertiesSOAErrorLibrary(); errLib.setName(assetInfo.getName()); errLib.setVersion(assetInfo.getVersion()); for (String domainName : StringUtils.split(props.getProperty( PropertiesSOAConstants.PROPS_LIST_OF_DOMAINS, ""), ",")) { PropertiesSOAErrorDomain domain = new PropertiesSOAErrorDomain(); domain.setLibrary(errLib); String domainFilePath = PropertiesSOAConstants.FOLDER_ERROR_DOMAIN_IN_JAR + "/" + domainName + "/" + PropertiesSOAConstants.FILE_ERROR_DATA; String errorPropFilePath = PropertiesSOAConstants.FOLDER_ERROR_DOMAIN_IN_JAR + "/" + domainName + "/" + defaultErrorPropertyName; URL domainUrl = classLoader.findResource(domainFilePath); URL errorPropUrl = classLoader.findResource(errorPropFilePath); if (domainUrl == null || errorPropUrl == null) { SOALogger.getLogger().log(Level.WARNING, "ErrorData.xml or error properties file is missing"); continue; } InputStream in = null; InputStream errorPropInput = null; Properties errorProperties = new Properties(); try { in = domainUrl.openStream(); errorPropInput = errorPropUrl.openStream(); errorProperties.load(errorPropInput); SOAErrorBundleVO bundle = ErrorObjectXMLParser.getErrorBundle(in); domain.setName(bundle.getDomain()); domain.setOrganization(bundle.getOrganization()); domain.setVersion(bundle.getVersion()); domain.setPackageName(bundle.getPackageName()); errLib.addErrorDomain(domain); for (SOAErrorVO vo : bundle.getList().getErrors()) { PropertiesSOAError err = new PropertiesSOAError(); err.setCategory(vo.getCategory()); err.setDomain(domain); err.setId(String.valueOf(vo.getId())); err.setName(vo.getName()); err.setSeverity(vo.getSeverity()); err.setSubDomain(vo.getSubdomain()); err.setMessage(errorProperties.getProperty(err.getName() + "." + PropertiesSOAConstants.PROPS_KEY_MESSAGE )); err.setResolution(errorProperties.getProperty(err.getName() + "." + PropertiesSOAConstants.PROPS_KEY_RESOLUTION)); domain.addError(err); } } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(errorPropInput); } } return errLib; } finally { if (classLoader != null) { classLoader.destroy(); } IOUtils.closeQuietly(ins); } } return null; } /* (non-Javadoc) * @see java.lang.Object#clone() */ @Override protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } /** * Adds the domain list props. * * @param project the project * @param domainName the domain name * @param monitor the monitor * @throws CoreException the core exception * @throws IOException Signals that an I/O exception has occurred. */ public static void addDomainListProps(IProject project, String domainName, IProgressMonitor monitor) throws CoreException, IOException { IFile file = TurmericErrorLibraryUtils.getDomainListPropsFile(project); OutputStream output = new ByteArrayOutputStream(); InputStream input = null; if (file.isAccessible()) { try { input = file.getContents(); String key = PropertiesSOAConstants.PROPS_LIST_OF_DOMAINS; Collection<String> domains = TurmericErrorLibraryUtils .getAllErrorDomains(project); if (!domains.contains(domainName)) { domains.add(domainName); } String domainListStr = StringUtils.join(domains, ","); // if (PropertiesFileUtil.getPropertyValueByKey(input, key) == null) { // input = file.getContents(); // Map<String, String> newProps = new HashMap<String, String>(); // newProps.put(key, domainListStr); // PropertiesFileUtil.addProperty(input, output, newProps); // } else { input = file.getContents(); PropertiesFileUtil.updatePropertyByKey(input, output, key, domainListStr); // } String contents = output.toString(); WorkspaceUtil.writeToFile(contents, file, monitor); } finally { IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } } } /** * Removes the domain from props. * * @param project the project * @param domainName the domain name * @throws IOException Signals that an I/O exception has occurred. * @throws CoreException the core exception */ public static void removeDomainFromProps(IProject project, String domainName) throws IOException, CoreException { IFile file = TurmericErrorLibraryUtils.getDomainListPropsFile(project); if (file.isAccessible()) { String key = PropertiesSOAConstants.PROPS_LIST_OF_DOMAINS; OutputStream output = null; InputStream input = null; try { output = new ByteArrayOutputStream(); input = file.getContents(); Collection<String> domains = TurmericErrorLibraryUtils .getAllErrorDomains(project); if (domains.contains(domainName)) { domains.remove(domainName); } String domainListStr = StringUtils.join(domains, ","); PropertiesFileUtil.updatePropertyByKey(input, output, key, domainListStr); String contents = output.toString(); WorkspaceUtil.writeToFile(contents, file, null); } finally { IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } } } /** * Removes the error from xml data. * * @param domainFolder the domain folder * @param error the error * @throws CoreException the core exception * @throws JDOMException the jDOM exception * @throws IOException Signals that an I/O exception has occurred. */ public static void removeErrorFromXmlData(IFolder domainFolder, ISOAError error) throws CoreException, JDOMException, IOException { IFile dataFile = domainFolder.getFile(PropertiesSOAConstants.FILE_ERROR_DATA); if (dataFile.isAccessible()) { InputStream input = null; try { input = dataFile.getContents(); SOAErrorBundleVO bundle = ErrorObjectXMLParser.getErrorBundle(input); SOAErrorVO toBeDeleted = null; for (SOAErrorVO vo : bundle.getList().getErrors()) { if (String.valueOf(vo.getId()).equals(error.getId())) { toBeDeleted = vo; break; } } if (toBeDeleted != null) { bundle.getList().removeError(toBeDeleted); } String contents = ErrorObjectXMLParser.convertErrorBundle(bundle); WorkspaceUtil.writeToFile(contents, dataFile, new NullProgressMonitor()); } finally { IOUtils.closeQuietly(input); } } } /** * Removes the error from props file. * * @param domainFolder the domain folder * @param error the error * @throws CoreException the core exception * @throws IOException Signals that an I/O exception has occurred. */ public static void removeErrorFromPropsFile(IFolder domainFolder, ISOAError error) throws CoreException, IOException { IFile propsFile = getErrorPropsFile(domainFolder); if (propsFile != null && propsFile.isAccessible()) { InputStream input = null; OutputStream output = new ByteArrayOutputStream(); try { input = propsFile.getContents(); String[] keysToBeDeleted = new String[2]; keysToBeDeleted[0] = error.getName() + "." + PropertiesSOAConstants.PROPS_KEY_MESSAGE; keysToBeDeleted[1] = error.getName() + "." + PropertiesSOAConstants.PROPS_KEY_RESOLUTION; PropertiesFileUtil.removePropertyByKey(input, output, keysToBeDeleted); String contents = output.toString(); WorkspaceUtil.writeToFile(contents, propsFile, new NullProgressMonitor()); } finally { IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } } } /** * Adds the error to props file. * * @param domainFolder the domain folder * @param model the model * @throws CoreException the core exception * @throws IOException Signals that an I/O exception has occurred. */ public static void addErrorToPropsFile(IFolder domainFolder, ErrorParamModel model) throws CoreException, IOException { IFile propsFile = getErrorPropsFile(domainFolder); if (propsFile != null && propsFile.isAccessible()) { InputStream input = null; OutputStream output = new ByteArrayOutputStream(); try { input = propsFile.getContents(); Map<String, String> newProps = new ConcurrentHashMap<String, String>(); newProps.put(model.getName() + "." + PropertiesSOAConstants.PROPS_KEY_MESSAGE, model.getMessage()); newProps.put(model.getName() + "." + PropertiesSOAConstants.PROPS_KEY_RESOLUTION, model.getResolution()); PropertiesFileUtil.addProperty(input, output, newProps); String contents = output.toString(); WorkspaceUtil.writeToFile(contents, propsFile, new NullProgressMonitor()); } finally { IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } } } }