/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, version 2 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details.
*/
package org.pentaho.platform.engine.core.solution;
import org.apache.commons.lang.StringUtils;
import org.pentaho.platform.api.repository.ISolutionRepository;
import org.pentaho.platform.api.util.PentahoCheckedChainedException;
public class ActionInfo {
/**
* TODO the method PentahoSystem.parseActionString() should be converted into a ctor for this class, and then removed. Callers should be adjusted.
* ActionResource.getLocationInSolution should be refactored into a method in this class, and callers adjusted. In general, the solutionName, path and
* actionName should likely be abstracted into an opaque class that can be passed around, instead of passing around 3 strings, and manually combining and
* parsing them in many places.
*
* @author Steven Barkdull
*
*/
private String solutionName;
private String path;
private String actionName;
public ActionInfo(final String solutionName, final String path, final String actionName) {
this.solutionName = solutionName;
this.path = path;
this.actionName = actionName;
}
public String getActionName() {
return actionName;
}
public String getPath() {
return path;
}
public String getSolutionName() {
return solutionName;
}
public static ActionInfo parseActionString(final String actionString) {
return ActionInfo.parseActionString(actionString, true);
}
// TODO sbarkdull, instead of returning null on parse error, should throw ActionInfoParseException
/**
* Break an action string into it's 3 components: the solution Id, the path to action file, and the action name
*
* @param actionString
* @return
*/
public static ActionInfo parseActionString(String actionString, boolean mustBeComplete) {
// parse a string in this format samples/reporting/JFR/report.xml into
// the solution, path, and document name
if (StringUtils.isEmpty(actionString)) {
return null;
}
// first normalize the path separators
actionString = actionString.replace('\\', ISolutionRepository.SEPARATOR);
// remove a leading '/'
if (actionString.charAt(0) == ISolutionRepository.SEPARATOR) {
actionString = actionString.substring(1);
}
String solution;
String path = ""; //$NON-NLS-1$
String name;
int idx1 = actionString.indexOf(ISolutionRepository.SEPARATOR);
int idx2 = actionString.lastIndexOf(ISolutionRepository.SEPARATOR);
if (idx1 == -1) {
if (mustBeComplete) {
// this is not a valid action String
return null;
} else {
return new ActionInfo(actionString, null, null);
}
}
solution = actionString.substring(0, idx1);
name = actionString.substring(idx2 + 1);
if (idx2 > idx1) {
path = actionString.substring(idx1 + 1, idx2);
}
// see if the name has an extension
if (!mustBeComplete && (name.indexOf('.') == -1)) {
// not really a filename
if (StringUtils.isEmpty(path)) {
path = name;
} else {
path = path + ISolutionRepository.SEPARATOR + name;
}
name = null;
}
return new ActionInfo(solution, path, name);
}
public String toString() {
return ActionInfo.buildSolutionPath(this.solutionName, this.path, this.actionName);
}
public static String buildSolutionPath(final String solution, String path, String filename) {
StringBuffer buf = new StringBuffer(ISolutionRepository.SEPARATOR);
// if the solutionName is the same as the fileName and the path is empty, then we are
// probably trying to load the solution root itself
if (solution != null && solution.equals(filename) && "".equals(path)) { //$NON-NLS-1$
filename = ""; //$NON-NLS-1$
}
if (path != null && path.equalsIgnoreCase("/")) { //$NON-NLS-1$
path = ""; //$NON-NLS-1$
}
if (StringUtils.isEmpty(path)) {
if (!StringUtils.isEmpty(filename) && filename.charAt(0) == ISolutionRepository.SEPARATOR) {
return buf.append(solution).append(filename).toString();
} else {
return buf.append(solution).append(ISolutionRepository.SEPARATOR).append(filename).toString();
}
} else if (path.charAt(0) == ISolutionRepository.SEPARATOR) {
if (!StringUtils.isEmpty(filename) && filename.charAt(0) == ISolutionRepository.SEPARATOR) {
return buf.append(solution).append(path).append(filename).toString();
} else {
return buf.append(solution).append(path).append(ISolutionRepository.SEPARATOR).append(filename).toString();
}
} else {
if (!StringUtils.isEmpty(filename) && filename.charAt(0) == ISolutionRepository.SEPARATOR) {
return buf.append(solution).append(ISolutionRepository.SEPARATOR).append(path).append(filename).toString();
} else {
return buf.append(solution).append(ISolutionRepository.SEPARATOR).append(path).append(ISolutionRepository.SEPARATOR).append(filename).toString();
}
}
}
public static class ActionInfoParseException extends PentahoCheckedChainedException {
private static final long serialVersionUID = 420;
public ActionInfoParseException(final String message, final Throwable reas) {
super(message, reas);
}
public ActionInfoParseException(final String message) {
super(message);
}
public ActionInfoParseException(final Throwable reas) {
super(reas);
}
public ActionInfoParseException() {
super();
}
}
}