/*
* P4Java - java integration with Perforce SCM
* Copyright (C) 2007-, Mike Wille, Tek42
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* You can contact the author at:
*
* Web: http://tek42.com
* Email: mike@tek42.com
* Mail: 755 W Big Beaver Road
* Suite 1110
* Troy, MI 48084
*/
package com.tek42.perforce.parse;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.tek42.perforce.PerforceException;
/**
* Abstract class that parses the stringbuilder into key/value pairs and then sends them to a abstract method
* responsible for building the object. If you extend this class, you do NOT override build(StringBuilder) but
* buildForm(Map).
* <p>
* Useful for all perforce objects that are editable via forms. i.e., User, Workspace, Jobspec, etc.
*
* @author Mike Wille
*/
public abstract class AbstractFormBuilder<T> implements Builder<T> {
private final Logger logger = LoggerFactory.getLogger("perforce");
/*
* (non-Javadoc)
*
* @see com.tek42.perforce.parse.Builder#build(java.lang.StringBuilder)
*/
public T build(StringBuilder sb) throws PerforceException {
// Allow our regexp to match with only one case and not have to handle the case for the last line
sb.append("Endp:\n");
logger.debug("Parsing: \n" + sb);
Pattern p = Pattern.compile("^(\\w+):(.*?)(?=\\n\\w{4,}?:)", Pattern.DOTALL | Pattern.MULTILINE);
Matcher m = p.matcher(sb.toString());
Map<String, String> fields = new HashMap<String, String>();
logger.debug("Parsing response...");
while(m.find()) {
String key = m.group(1);
String value = m.group(2).trim();
fields.put(key, value);
logger.debug("Have key: " + key + " = " + value);
}
return buildForm(fields);
}
/**
* Test for null and returns an empty string if the key is not present. Otherwise, returns the value.
*
* @param key
* @param fields
* @return
*/
protected String getField(String key, Map<String, String> fields) {
String value = fields.get(key);
if(value == null)
return "";
return value;
}
/**
* Like getField(String, Map) except that it assumes the value of the field is a String containing a
* delimited list of values. It parses the string into a string list. Assumes new line as separator.
* @param key The name of the field.
* @param fields The map of field/value pairs.
* @return A List of strings.
*/
protected List<String> getFieldAsList(String key, Map<String, String> fields) {
String value = fields.get(key);
if(value == null || value.equals("") || value.equals("\n"))
return new ArrayList<String>();
String values[] = value.split("\\n");
List<String> list = new ArrayList<String>(values.length);
list.addAll(Arrays.asList(values));
return list;
}
/**
* Default implementation for most Perforce operations is to use stdin. This will return true.
* @return True always
*/
public boolean requiresStandardInput() {
return true;
}
/**
* Should return a new object set with the data from fields.
*
* @param fields
* @return
* @throws PerforceException
*/
public abstract T buildForm(Map<String, String> fields) throws PerforceException;
}