blob: 474f873ed3d101f732a51dcfa18b36f0d1d9115e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.chemistry.opencmis.server.impl.browser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.commons.impl.Constants;
/**
* Parses HTML form controls.
*/
public class ControlParser {
public static final String CONTROL_PROP_ID_LOWER = "propertyid";
private static final String CONTROL_PROP_VALUE_LOWER = "propertyvalue";
private final HttpServletRequest request;
private final Map<String, String> zeroDim = new HashMap<String, String>();
private final Map<String, Map<Integer, String>> oneDim = new HashMap<String, Map<Integer, String>>();
private final Map<String, Map<Integer, Map<Integer, String>>> twoDim = new HashMap<String, Map<Integer, Map<Integer, String>>>();
public ControlParser(HttpServletRequest request) {
this.request = request;
parse();
}
@SuppressWarnings("unchecked")
private void parse() {
// gather all controls
Map<String, String[]> controls = request.getParameterMap();
if (controls == null) {
return;
}
for (Map.Entry<String, String[]> control : controls.entrySet()) {
String controlName = control.getKey().trim().toLowerCase(Locale.ENGLISH);
int firstIndex = getFirstIndex(controlName);
if (firstIndex == -1) {
zeroDim.put(controlName, control.getValue()[0]);
} else {
String strippedControlName = controlName.substring(0, controlName.indexOf('['));
int secondIndex = getSecondIndex(controlName);
if (secondIndex == -1) {
Map<Integer, String> values = oneDim.get(strippedControlName);
if (values == null) {
values = new HashMap<Integer, String>();
oneDim.put(strippedControlName, values);
}
values.put(firstIndex, control.getValue()[0]);
} else {
Map<Integer, Map<Integer, String>> values = twoDim.get(strippedControlName);
if (values == null) {
values = new HashMap<Integer, Map<Integer, String>>();
twoDim.put(strippedControlName, values);
}
Map<Integer, String> list = values.get(firstIndex);
if (list == null) {
list = new HashMap<Integer, String>();
values.put(firstIndex, list);
}
list.put(secondIndex, control.getValue()[0]);
}
}
}
}
private static int getFirstIndex(String controlName) {
int result = -1;
int open = controlName.indexOf('[');
int close = controlName.indexOf(']');
if (open == -1 || close == -1 || close < open) {
return result;
}
String indexStr = controlName.substring(open + 1, close);
try {
result = Integer.parseInt(indexStr);
if (result < 0) {
result = -1;
}
} catch (NumberFormatException e) {
// return default value (-1)
}
return result;
}
private static int getSecondIndex(String controlName) {
int result = -1;
int open = controlName.indexOf("][");
int close = controlName.lastIndexOf(']');
if (open == -1 || close == -1 || close < open) {
return result;
}
String indexStr = controlName.substring(open + 2, close);
try {
result = Integer.parseInt(indexStr);
if (result < 0) {
result = -1;
}
} catch (NumberFormatException e) {
// return default value (-1)
}
return result;
}
private static List<String> convertToList(String controlName, Map<Integer, String> map) {
if (map == null) {
return null;
}
int count = map.size();
List<String> result = new ArrayList<String>(count);
for (int i = 0; i < count; i++) {
String value = map.get(i);
if (value == null) {
throw new CmisInvalidArgumentException(controlName + " has gaps!");
}
result.add(value);
}
return result;
}
public String getValue(String controlName) {
if (controlName == null) {
throw new IllegalArgumentException("controlName must not be null!");
}
return zeroDim.get(controlName.toLowerCase(Locale.ENGLISH));
}
public List<String> getValues(String controlName) {
if (controlName == null) {
throw new IllegalArgumentException("controlName must not be null!");
}
return convertToList(controlName, oneDim.get(controlName.toLowerCase(Locale.ENGLISH)));
}
public List<String> getValues(String controlName, int index) {
if (controlName == null) {
throw new IllegalArgumentException("controlName must not be null!");
}
Map<Integer, Map<Integer, String>> map = twoDim.get(controlName.toLowerCase(Locale.ENGLISH));
if (map == null) {
return null;
}
return convertToList(controlName, map.get(index));
}
public Map<Integer, String> getOneDimMap(String controlName) {
if (controlName == null) {
throw new IllegalArgumentException("controlName must not be null!");
}
return oneDim.get(controlName.toLowerCase(Locale.ENGLISH));
}
public Map<Integer, Map<Integer, String>> getTwoDimMap(String controlName) {
if (controlName == null) {
throw new IllegalArgumentException("controlName must not be null!");
}
return twoDim.get(controlName.toLowerCase(Locale.ENGLISH));
}
public Map<String, List<String>> getProperties() {
Map<Integer, String> propertyIds = oneDim.get(CONTROL_PROP_ID_LOWER);
if (propertyIds == null) {
return null;
}
Map<Integer, String> oneDimPropValues = oneDim.get(CONTROL_PROP_VALUE_LOWER);
Map<Integer, Map<Integer, String>> twoDimPropValues = twoDim.get(CONTROL_PROP_VALUE_LOWER);
int count = propertyIds.size();
Map<String, List<String>> result = new LinkedHashMap<String, List<String>>();
for (int i = 0; i < count; i++) {
String propertyId = propertyIds.get(i);
if (propertyId == null) {
throw new CmisInvalidArgumentException(Constants.CONTROL_PROP_ID + " has gaps!");
}
List<String> values = null;
if (oneDimPropValues != null && oneDimPropValues.containsKey(i)) {
values = Collections.singletonList(oneDimPropValues.get(i));
} else if (twoDimPropValues != null && twoDimPropValues.containsKey(i)) {
values = new ArrayList<String>();
Map<Integer, String> valuesMap = twoDimPropValues.get(i);
if (valuesMap != null) {
int valueCount = valuesMap.size();
for (int j = 0; j < valueCount; j++) {
String value = valuesMap.get(j);
if (value == null) {
throw new CmisInvalidArgumentException(Constants.CONTROL_PROP_VALUE + "[" + i
+ "] has gaps!");
}
values.add(value);
}
}
}
result.put(propertyId, values);
}
return result;
}
}