001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.settings;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.resource.ResourceRetriever;
019    import com.liferay.portal.kernel.resource.manager.ResourceManager;
020    import com.liferay.portal.kernel.util.StringUtil;
021    
022    import java.io.FileInputStream;
023    import java.io.IOException;
024    
025    /**
026     * @author Iv??n Zaera
027     */
028    public class LocationVariableResolver {
029    
030            public LocationVariableResolver(
031                    ResourceManager resourceManager, SettingsFactory settingsFactory) {
032    
033                    _resourceManager = resourceManager;
034                    _settingsFactory = settingsFactory;
035            }
036    
037            public boolean isLocationVariable(String value) {
038                    if (value == null) {
039                            return false;
040                    }
041    
042                    if (value.startsWith(_LOCATION_VARIABLE_START) &&
043                            value.endsWith(_LOCATION_VARIABLE_END) &&
044                            value.contains(_LOCATION_VARIABLE_PROTOCOL_SEPARATOR)) {
045    
046                            return true;
047                    }
048    
049                    return false;
050            }
051    
052            public String resolve(String value) {
053                    String protocol = _getProtocol(value);
054                    String location = _getLocation(value);
055    
056                    if (protocol.equals("resource")) {
057                            return _resolveResource(location);
058                    }
059                    else if (protocol.equals("file")) {
060                            return _resolveFile(location);
061                    }
062                    else if (protocol.equals("server-property")) {
063                            return _resolveServerProperty(location);
064                    }
065    
066                    throw new UnsupportedOperationException(
067                            "Unsupported protocol " + protocol);
068            }
069    
070            private String _getLocation(String value) {
071                    int i = value.indexOf(_LOCATION_VARIABLE_PROTOCOL_SEPARATOR);
072    
073                    return value.substring(i+1, value.length()-1);
074            }
075    
076            private String _getProtocol(String value) {
077                    int i = value.indexOf(_LOCATION_VARIABLE_PROTOCOL_SEPARATOR);
078    
079                    return value.substring(2, i);
080            }
081    
082            private String _resolveFile(String location) {
083                    if (!location.startsWith("///")) {
084                            throw new IllegalArgumentException(
085                                    "Invalid file location " + location + " because only local " +
086                                            "file URIs starting with file:/// are supported");
087                    }
088    
089                    try {
090                            return StringUtil.read(new FileInputStream(location.substring(2)));
091                    }
092                    catch (IOException ioe) {
093                            throw new SystemException("Unable to read file " + location, ioe);
094                    }
095            }
096    
097            private String _resolveResource(String location) {
098                    ResourceRetriever resourceRetriever =
099                            _resourceManager.getResourceRetriever(location);
100    
101                    try {
102                            return StringUtil.read(resourceRetriever.getInputStream());
103                    }
104                    catch (IOException ioe) {
105                            throw new SystemException(
106                                    "Unable to read resource " + location, ioe);
107                    }
108            }
109    
110            private String _resolveServerProperty(String location) {
111                    if (!location.startsWith("//")) {
112                            throw new IllegalArgumentException(
113                                    "Invalid server property location " + location);
114                    }
115    
116                    location = location.substring(2);
117    
118                    int i = location.indexOf("/");
119    
120                    if (i == -1) {
121                            throw new IllegalArgumentException(
122                                    "Invalid server property location " + location);
123                    }
124    
125                    String serviceName = location.substring(0, i);
126    
127                    Settings settings = _settingsFactory.getServerSettings(serviceName);
128    
129                    String property = location.substring(i+1);
130    
131                    return settings.getValue(property, null);
132            }
133    
134            private static final String _LOCATION_VARIABLE_END = "}";
135    
136            private static final String _LOCATION_VARIABLE_PROTOCOL_SEPARATOR = ":";
137    
138            private static final String _LOCATION_VARIABLE_START = "${";
139    
140            private final ResourceManager _resourceManager;
141            private final SettingsFactory _settingsFactory;
142    
143    }