Package org.mevenide.idea.project.properties

Source Code of org.mevenide.idea.project.properties.PropertiesManager

package org.mevenide.idea.project.properties;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mevenide.idea.global.MavenManager;
import org.mevenide.idea.project.PomManager;
import org.mevenide.idea.util.FileUtils;
import org.mevenide.idea.util.components.AbstractProjectComponent;

/**
* Resolves Maven properties by looking in all possible places - POM property files, user files,
* system properties and in the Maven installation itself.
*
* <p>Resolves property values by supporting the "${property}" property expression convention (which
* is used by Maven).</p>
*
* @author Arik
*/
public class PropertiesManager extends AbstractProjectComponent {
    /**
     * Logging.
     */
    private static final Log LOG = LogFactory.getLog(PropertiesManager.class);

    /**
     * Creates an instance for the given project.
     *
     * @param pProject the project
     */
    public PropertiesManager(final Project pProject) {
        super(pProject);
    }

    /**
     * Returns the value of the given property. The value is located the same way Maven resolves
     * properties - in the following order:
     *
     * <p><ol> <li>system properties ({@code -Dx=y})</li> <li>user's properties ({@code
     * build.properties} under the user's home)</li> <li>maven properties (maven-provided
     * defaults)</li> </ol></p>
     *
     * <p><b>Note:</b> that this method does NOT evaluate project properties, as it is intended to
     * be used for global properties only.</p>
     *
     * @param pName name of the property to resolve
     *
     * @return property value, or {@code null} if it could not be found
     */
    public String getProperty(final String pName) {
        return getProperty(null, pName);
    }

    /**
     * Returns the value of the given property. The value is located the same way Maven resolves
     * properties - in the following order:
     *
     * <p><ol> <li>system properties ({@code -Dx=y})</li> <li>user's properties ({@code
     * build.properties} under the user's home)</li> <li>build properties ({@code build.properties}
     * in the POM directory)</li> <li>project properties ({@code project.properties} in the POM
     * directory</li> <li>maven properties (maven-provided defaults)</li> </ol></p>
     *
     * @param pPomUrl the POM file url for which we resolve the property. The POM is needed, since
     *                each POM defines its own set of properties
     * @param pName   name of the property to resolve
     *
     * @return property value, or {@code null} if it could not be found
     */
    public String getProperty(final String pPomUrl, final String pName) {
        final VirtualFile pPomFile = PomManager.getInstance(project).getFile(pPomUrl);

        //
        //check some preconfigured properties that are not present in
        //configuration files, but Maven expects them because they are
        //passed by the maven shell scripts
        //
        final MavenManager mavenMgr = MavenManager.getInstance();
        final VirtualFile mavenHome = mavenMgr.getMavenHome();
        if (pName.equals("maven.home"))
            return mavenHome == null ? null : mavenHome.getPath();

        //
        //system properties
        //
        String value = System.getProperty(pName);
        if (value != null && value.trim().length() > 0)
            return resolveProperty(pPomFile, value);

        //
        //user properties
        //
        try {
            final VirtualFile home = getUserHome();
            if (home != null && home.isValid() && home.isDirectory() && FileUtils.exists(home)) {
                final VirtualFile propsFile = home.findChild("build.properties");
                if (propsFile != null && propsFile.isValid() && !propsFile.isDirectory() && FileUtils.exists(
                        propsFile)) {
                    value = getFilePropertyValue(propsFile, pName);
                    if (value != null)
                        return resolveProperty(pPomFile, value);
                }
            }
        }
        catch (IOException e) {
            LOG.warn(e.getMessage(), e);
        }

        //
        //starting to use POM - get POM directory
        //
        if (pPomFile != null) {
            final VirtualFile dir = pPomFile.getParent();
            if (dir != null) {
                //
                //build properties
                //
                try {
                    value = getFilePropertyValue(dir, "build.properties", pName);
                    if (value != null)
                        return resolveProperty(pPomFile, value);
                }
                catch (IOException e) {
                    LOG.warn(e.getMessage(), e);
                }

                //
                //project properties
                //
                try {
                    value = getFilePropertyValue(dir, "project.properties", pName);
                    if (value != null)
                        return resolveProperty(pPomFile, value);
                }
                catch (IOException e) {
                    LOG.warn(e.getMessage(), e);
                }
            }
        }

        if (mavenHome == null || !FileUtils.exists(mavenHome) || !mavenHome.isValid() || !mavenHome.isDirectory())
            return null;
        final String baseJarUrl = "jar://" + mavenHome.getPath() + "/lib/maven.jar!/";

        //
        //maven defaults properties
        //
        try {
            final String url = baseJarUrl + "defaults.properties";
            final VirtualFile propsFile = VirtualFileManager.getInstance().findFileByUrl(url);
            if (propsFile != null) {
                value = getFilePropertyValue(propsFile, pName);
                if (value != null)
                    return resolveProperty(pPomFile, value);
            }
        }
        catch (IOException e) {
            LOG.warn(e.getMessage(), e);
        }

        //
        //maven driver properties
        //
        try {
            final String url = baseJarUrl + "driver.properties";
            final VirtualFile propsFile = VirtualFileManager.getInstance().findFileByUrl(url);
            if (propsFile != null) {
                value = getFilePropertyValue(propsFile, pName);
                if (value != null)
                    return resolveProperty(pPomFile, value);
            }
        }
        catch (IOException e) {
            LOG.warn(e.getMessage(), e);
        }

        return null;
    }

    /**
     * Resolves all property expressions in the given string to their values. Property expressions
     * are written in the familiar format of {@code ${propertyname}}.
     *
     * @param pPomUrl the POM by which property values will be fetched if needed
     * @param pValue  the string containing expressions
     *
     * @return expanded string with property values
     */
    public String resolveProperty(final String pPomUrl, final String pValue) {
        final VirtualFile pomFile = PomManager.getInstance(project).getFile(pPomUrl);
        return resolveProperty(pomFile, pValue);
    }

    /**
     * Resolves all property expressions in the given string to their values. Property expressions
     * are written in the familiar format of {@code ${propertyname}}.
     *
     * @param pPomFile the POM by which property values will be fetched if needed
     * @param pValue   the string containing expressions
     *
     * @return expanded string with property values
     */
    public String resolveProperty(final VirtualFile pPomFile, final String pValue) {
        final StringBuilder buf = new StringBuilder(pValue);

        int exprStart = buf.indexOf("$");
        while (exprStart >= 0) {
            if (exprStart < buf.length() - 1) {
                final char next = buf.charAt(exprStart + 1);
                if (next == '{') {
                    final int exprEnd = buf.indexOf("}", exprStart);
                    if (exprEnd >= 0) {
                        final String expr = buf.substring(exprStart + 2, exprEnd);
                        final String url = pPomFile == null ? null : pPomFile.getUrl();
                        final String value = getProperty(url, expr);
                        buf.replace(exprStart, exprEnd + 1, value == null ? "" : value);
                        exprStart--;
                    }
                }
            }

            exprStart++;
            exprStart = buf.indexOf("$", exprStart);
        }

        return buf.toString();
    }

    /**
     * Returns the user's home directory, or {@code null} if it can't be found.
     *
     * @return file
     */
    private VirtualFile getUserHome() {
        final String homePath = System.getProperty("user.home");
        final String fixedPath = homePath.replace(File.separatorChar, '/');
        final String homeUrl = VirtualFileManager.constructUrl("file", fixedPath);
        return VirtualFileManager.getInstance().findFileByUrl(homeUrl);
    }

    /**
     * Searches for the given property in the specified file, and if found, returns its value. If
     * the property is not found, {@code null} is returned.
     *
     * <p><b>Note:</b> this method does not resolve the value - it is returned "raw".</p>
     *
     * @param pFile the file to search in
     * @param pName the name of the property to search for
     *
     * @return property value as a string, or {@code null} if not found
     * @throws IOException if an error occurs while reading the file
     */
    private String getFilePropertyValue(final VirtualFile pFile, final String pName)
            throws IOException {
        final Properties props = new Properties();
        props.load(new ByteArrayInputStream(pFile.contentsToByteArray()));
        return props.getProperty(pName);
    }

    /**
     * Searches for the given property in a file, and if found, returns its value. If the property
     * or file is not found, {@code null} is returned.
     *
     * <p>The file that is searched is the file that corresponds to the relative path specified. The
     * path is resolved against the {@code pFile} argument.</p>
     *
     * <p><b>Note:</b> this method does not resolve the value - it is returned "raw".</p>
     *
     * @param pFile the file to search in
     * @param pName the name of the property to search for
     *
     * @return property value as a string, or {@code null} if not found
     * @throws IOException if an error occurs while reading the file
     */
    private String getFilePropertyValue(final VirtualFile pFile,
                                        final String pChildFileName,
                                        final String pName) throws IOException {
        final VirtualFile child = pFile.findFileByRelativePath(pChildFileName);
        if (child != null && child.isValid() && !child.isDirectory() && FileUtils.exists(child))
            return getFilePropertyValue(child, pName);
        else
            return null;
    }

    /**
     * Returns an instance of the component.
     *
     * @return instance
     */
    public static PropertiesManager getInstance(final Project pProject) {
        return pProject.getComponent(PropertiesManager.class);
    }
}
TOP

Related Classes of org.mevenide.idea.project.properties.PropertiesManager

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.