提交 971ceda7 编写于 作者: F frederikheremans

Added pluggable URL-navigation

上级 8c5434c4
......@@ -74,7 +74,7 @@ public class ProcessEngineFactoryBean implements FactoryBean<ProcessEngine>, Dis
}
}
public Class< ? > getObjectType() {
public Class<ProcessEngine> getObjectType() {
return ProcessEngine.class;
}
......
......@@ -22,10 +22,10 @@ import org.activiti.engine.ProcessEngines;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.explorer.navigation.NavigationFragmentChangeListener;
import org.activiti.explorer.navigation.UriFragment;
import org.activiti.explorer.ui.MainLayout;
import com.vaadin.Application;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.UriFragmentUtility;
......@@ -43,6 +43,7 @@ public class ExplorerApplication extends Application implements HttpServletReque
protected Window mainWindow;
protected MainLayout mainLayout;
protected UriFragmentUtility uriFragmentUtility;
protected UriFragment currentUriFragment;
public void init() {
......@@ -125,7 +126,33 @@ public class ExplorerApplication extends Application implements HttpServletReque
uriFragmentUtility.addListener(new NavigationFragmentChangeListener());
}
public UriFragmentUtility getUriFragmentUtility() {
return uriFragmentUtility;
public UriFragment getCurrentUriFragment() {
return currentUriFragment;
}
/**
* Sets the current {@link UriFragment}.
* Won't trigger navigation, just updates the URI fragment in the browser.
*/
public void setCurrentUriFragment(UriFragment fragment) {
this.currentUriFragment = fragment;
if(fragmentChanged(fragment)) {
if(fragment != null) {
uriFragmentUtility.setFragment(fragment.toString(), false);
} else {
uriFragmentUtility.setFragment("", false);
}
}
}
private boolean fragmentChanged(UriFragment fragment) {
String fragmentString = fragment.toString();
if(fragmentString == null) {
return uriFragmentUtility.getFragment() != null;
} else {
return !fragmentString.equals(uriFragmentUtility.getFragment());
}
}
}
/* Licensed 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.activiti.explorer.navigation;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.ui.management.db.DatabasePage;
/**
* @author Frederik Heremans
*/
public class DataBaseNavigationHandler implements NavigationHandler {
public static final String TABLE_URI_PART = "database";
public String getTrigger() {
return TABLE_URI_PART;
}
public void handleNavigation(UriFragment uriFragment) {
String tableName = uriFragment.getUriPart(1);
if (tableName != null) {
ExplorerApplication.getCurrent().switchView(new DatabasePage(tableName));
} else {
ExplorerApplication.getCurrent().switchView(new DatabasePage());
}
}
}
/* Licensed 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.activiti.explorer.navigation;
/**
* @author Frederik Heremans
*/
public class DefaultNavigationHandler implements NavigationHandler {
public String getTrigger() {
// Handles all non-matched navigation events, we can return null.
return null;
}
public void handleNavigation(UriFragment uriFragment) {
// TODO: What should happen with unhandled URL's?
}
}
/* Licensed 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.activiti.explorer.navigation;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.ui.management.deployment.DeploymentPage;
/**
* @author Frederik Heremans
*/
public class DeploymentNavigationHandler implements NavigationHandler {
public static final String DEPLOYMENT_URI_PART = "deployment";
public String getTrigger() {
return DEPLOYMENT_URI_PART;
}
public void handleNavigation(UriFragment uriFragment) {
String deploymentId = uriFragment.getUriPart(1);
if(deploymentId != null) {
ExplorerApplication.getCurrent().switchView(new DeploymentPage(deploymentId));
} else {
ExplorerApplication.getCurrent().switchView(new DeploymentPage());
}
}
}
/* Licensed 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.activiti.explorer.navigation;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.ui.flow.FlowPage;
/**
* @author Frederik Heremans
*/
public class FlowNavigationHandler implements NavigationHandler {
public static final String FLOW_URI_PART = "flows";
public String getTrigger() {
return FLOW_URI_PART;
}
public void handleNavigation(UriFragment uriFragment) {
String processDefinitionId = uriFragment.getUriPart(1);
if(processDefinitionId != null) {
ExplorerApplication.getCurrent().switchView(new FlowPage(processDefinitionId));
} else {
ExplorerApplication.getCurrent().switchView(new FlowPage());
}
}
}
......@@ -14,7 +14,6 @@
package org.activiti.explorer.navigation;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.ui.task.TaskInboxPage;
import com.vaadin.ui.UriFragmentUtility.FragmentChangedEvent;
import com.vaadin.ui.UriFragmentUtility.FragmentChangedListener;
......@@ -31,22 +30,25 @@ public class NavigationFragmentChangeListener implements FragmentChangedListener
private static final long serialVersionUID = 4797018291237796530L;
public void fragmentChanged(FragmentChangedEvent source) {
String fragment = source.getUriFragmentUtility().getFragment();
UriFragment uriFragment = new UriFragment(fragment);
// TODO: make more flexible, pluggable fragment-matchers and URL-encoding aware parsing.
String fragment = source.getUriFragmentUtility().getFragment().replace("#", "");
if(fragment != null && fragment.length() > 0) {
String[] fragments = fragment.split("/");
System.out.println("Got fragment: " + fragment);
if("tasks".equals(fragments[0])) {
String taskId = fragments[1];
System.out.println("Task ID in fragment: " + fragments[1]);
ExplorerApplication.getCurrent().switchView(new TaskInboxPage(taskId));
}
// Find appropriate handler based on the first part of the URI
NavigationHandler navigationHandler = null;
if(uriFragment.getUriParts() != null && uriFragment.getUriParts().size() > 0) {
navigationHandler = NavigationHandlers.getHandler(uriFragment.getUriParts().get(0));
}
if(navigationHandler == null) {
navigationHandler = NavigationHandlers.getDefaultHandler();
}
// Delegate navigation to handler
navigationHandler.handleNavigation(uriFragment);
// Set the parameter and parts on the current ExplorerApplication
ExplorerApplication.getCurrent().setCurrentUriFragment(uriFragment);
}
}
/* Licensed 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.activiti.explorer.navigation;
/**
* Handler class for responding on navigation requests.
*
* @author Frederik Heremans
*/
public interface NavigationHandler {
/**
* Gets the string that triggers this handler to be used
* when navigation should be performed. This is the first part of
* the uri-fragment.
*/
String getTrigger();
/**
* Handle the incoming navigation request. The url-fragment passed contains all
* uri parts that triggered the navigation request (including the one returned by
* {@link NavigationHandler#getTrigger()}), as well as the parameters contain
* the values of the parameters passed in the query string (if any).
*/
void handleNavigation(UriFragment uriFragment);
}
/* Licensed 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.activiti.explorer.navigation;
import java.util.HashMap;
import java.util.Map;
/**
* @author Frederik Heremans
*/
public class NavigationHandlers {
protected static Map<String, NavigationHandler> navigationHandlers = new HashMap<String, NavigationHandler>();
protected static NavigationHandler defaultHandler;
public static void addNavigationHandler(NavigationHandler handler) {
navigationHandlers.put(handler.getTrigger(), handler);
}
public static NavigationHandler getHandler(String trigger) {
if (trigger != null) {
return navigationHandlers.get(trigger);
}
return null;
}
public static NavigationHandler getDefaultHandler() {
if(defaultHandler == null) {
throw new IllegalStateException("No default navigation handler has been set");
}
return defaultHandler;
}
public static void setDefaultHandler(NavigationHandler handler) {
defaultHandler = handler;
}
}
/* Licensed 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.activiti.explorer.navigation;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.ui.task.TaskInboxPage;
/**
* @author Frederik Heremans
*/
public class TaskNavigationHandler implements NavigationHandler {
public static final String TASK_URI_PART = "tasks";
public static final String CATEGORY_INBOX = "inbox";
public String getTrigger() {
return TASK_URI_PART;
}
public void handleNavigation(UriFragment uriFragment) {
// String category = uriFragment.getParameter(CATEGORY_INBOX);
String taskId = null;
if (uriFragment.getUriParts().size() == 2) {
taskId = uriFragment.getUriPart(1);
}
if (taskId != null) {
ExplorerApplication.getCurrent().switchView(new TaskInboxPage(taskId));
} else {
ExplorerApplication.getCurrent().switchView(new TaskInboxPage());
}
}
}
/* Licensed 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.activiti.explorer.navigation;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.activiti.explorer.util.UriUtility;
/**
* Class containing parts of an uri-fragment (eg: "task", "inbox", "123") and
* parameters based on the URL's query string.
*
* @author Frederik Heremans
*/
public class UriFragment {
private List<String> uriParts;
private Map<String, String> parameters;
public UriFragment(String fragment) {
// Extract fragment parts
String fragmentUri = UriUtility.extractUri(fragment);
uriParts = UriUtility.getFragmentParts(fragmentUri);
// Extract parameters
String queryString = UriUtility.extractQueryString(fragment);
parameters = UriUtility.parseQueryParameters(queryString, null);
}
public UriFragment(List<String> uriParts, Map<String, String> parameters) {
this.uriParts = uriParts;
this.parameters = parameters;
}
public UriFragment(Map<String, String> parameters, String... uriParts) {
this.uriParts = Arrays.asList(uriParts);
this.parameters = parameters;
}
public UriFragment(String... uriParts) {
this.uriParts = Arrays.asList(uriParts);
this.parameters = new LinkedHashMap<String, String>();
}
public void addParameter(String name, String value) {
parameters.put(name, value);
}
public List<String> getUriParts() {
return uriParts;
}
public Map<String, String> getParameters() {
return parameters;
}
public String getParameter(String name) {
if (parameters != null) {
return parameters.get(name);
}
return null;
}
public String getUriPart(int index) {
if (index >= 0 && index < uriParts.size()) {
return uriParts.get(index);
}
return null;
}
@Override
public String toString() {
return UriUtility.getPath(uriParts) + UriUtility.getQueryString(parameters);
}
}
......@@ -29,6 +29,12 @@ import org.activiti.engine.identity.User;
import org.activiti.engine.impl.util.ClockUtil;
import org.activiti.engine.impl.util.IoUtil;
import org.activiti.engine.task.Task;
import org.activiti.explorer.navigation.DataBaseNavigationHandler;
import org.activiti.explorer.navigation.DefaultNavigationHandler;
import org.activiti.explorer.navigation.DeploymentNavigationHandler;
import org.activiti.explorer.navigation.FlowNavigationHandler;
import org.activiti.explorer.navigation.NavigationHandlers;
import org.activiti.explorer.navigation.TaskNavigationHandler;
import org.activiti.explorer.ui.form.DateFormPropertyRenderer;
import org.activiti.explorer.ui.form.EnumFormPropertyRenderer;
import org.activiti.explorer.ui.form.FormPropertyMapping;
......@@ -51,9 +57,9 @@ public class BootProcessEngineContextListener implements ServletContextListener
}
initFormPropertyMapping();
initUriNavigation();
initDemoData();
}
protected void initDemoData() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
......@@ -76,6 +82,17 @@ public class BootProcessEngineContextListener implements ServletContextListener
// Set default renderer when property has null type
FormPropertyMapping.setNoTypePropertyRenderer(stringRenderer);
}
protected void initUriNavigation() {
DefaultNavigationHandler defaultHandler = new DefaultNavigationHandler();
NavigationHandlers.setDefaultHandler(defaultHandler);
// Add other handlers
NavigationHandlers.addNavigationHandler(new TaskNavigationHandler());
NavigationHandlers.addNavigationHandler(new FlowNavigationHandler());
NavigationHandlers.addNavigationHandler(new DeploymentNavigationHandler());
NavigationHandlers.addNavigationHandler(new DataBaseNavigationHandler());
}
protected void initKermit(ProcessEngine processEngine) {
// Create Kermit demo user
......
......@@ -22,6 +22,8 @@ import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.Images;
import org.activiti.explorer.data.LazyLoadingContainer;
import org.activiti.explorer.data.LazyLoadingQuery;
import org.activiti.explorer.navigation.FlowNavigationHandler;
import org.activiti.explorer.navigation.UriFragment;
import org.activiti.explorer.ui.util.ThemeImageColumnGenerator;
import com.vaadin.data.Item;
......@@ -58,6 +60,10 @@ public class FlowPage extends VerticalLayout {
initFlowMenuBar();
initMainSplitPanel();
initProcessDefinitionList();
// Set URL
ExplorerApplication.getCurrent().setCurrentUriFragment(
new UriFragment(FlowNavigationHandler.FLOW_URI_PART));
}
/**
......@@ -126,8 +132,8 @@ public class FlowPage extends VerticalLayout {
detailPanel = new ProcessDefinitionDetailPanel(processDefinitionId, FlowPage.this);
mainSplitPanel.setSecondComponent(detailPanel);
// Update URI
ExplorerApplication.getCurrent().getUriFragmentUtility().setFragment("flow/" + processDefinitionId, false);
UriFragment processDefinitionFragment = new UriFragment(FlowNavigationHandler.FLOW_URI_PART, processDefinitionId);
ExplorerApplication.getCurrent().setCurrentUriFragment(processDefinitionFragment);
}
public void showStartForm(ProcessDefinition processDefinition, StartFormData startFormData) {
......
......@@ -16,7 +16,10 @@ import java.util.TreeMap;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngines;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.Images;
import org.activiti.explorer.navigation.DataBaseNavigationHandler;
import org.activiti.explorer.navigation.UriFragment;
import org.activiti.explorer.ui.management.ManagementPage;
import com.vaadin.data.Item;
......@@ -45,6 +48,16 @@ public class DatabasePage extends ManagementPage {
addTableList();
populateTableList();
ExplorerApplication.getCurrent().setCurrentUriFragment(
new UriFragment(DataBaseNavigationHandler.TABLE_URI_PART));
}
public DatabasePage(String tableName) {
this();
// Select the requested table
tableList.select(tableName);
}
protected void addTableList() {
......@@ -63,7 +76,12 @@ public class DatabasePage extends ManagementPage {
private static final long serialVersionUID = 8811553575319455854L;
public void valueChange(ValueChangeEvent event) {
// The itemId of the table list is the tableName
mainSplitPanel.setSecondComponent(new DatabaseDetailPanel((String) event.getProperty().getValue()));
String tableName = (String) event.getProperty().getValue();
mainSplitPanel.setSecondComponent(new DatabaseDetailPanel(tableName));
// Update URL
ExplorerApplication.getCurrent().setCurrentUriFragment(
new UriFragment(DataBaseNavigationHandler.TABLE_URI_PART, tableName));
}
});
......
......@@ -12,10 +12,12 @@
*/
package org.activiti.explorer.ui.management.deployment;
import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.data.LazyLoadingContainer;
import org.activiti.explorer.data.LazyLoadingQuery;
import org.activiti.explorer.navigation.DeploymentNavigationHandler;
import org.activiti.explorer.navigation.UriFragment;
import org.activiti.explorer.ui.management.ManagementPage;
import org.activiti.explorer.ui.task.TaskDetailPanel;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
......@@ -32,8 +34,17 @@ public class DeploymentPage extends ManagementPage {
protected Table deploymentTable;
protected LazyLoadingContainer deploymentListContainer;
public DeploymentPage() {
addDeploymentList();
ExplorerApplication.getCurrent().setCurrentUriFragment(
new UriFragment(DeploymentNavigationHandler.DEPLOYMENT_URI_PART));
}
public DeploymentPage(String deploymentId) {
this();
selectDeployment(deploymentListContainer.getIndexForObjectId(deploymentId));
}
protected void addDeploymentList() {
......@@ -48,16 +59,20 @@ public class DeploymentPage extends ManagementPage {
deploymentTable.setSizeFull();
LazyLoadingQuery deploymentListQuery = new DeploymentListQuery();
LazyLoadingContainer deploymentListContainer = new LazyLoadingContainer(deploymentListQuery, 10);
deploymentListContainer = new LazyLoadingContainer(deploymentListQuery, 10);
deploymentTable.setContainerDataSource(deploymentListContainer);
// Listener to change right panel when clicked on a task
// Listener to change right panel when clicked on a deployment
deploymentTable.addListener(new Property.ValueChangeListener() {
private static final long serialVersionUID = 8811553575319455854L;
public void valueChange(ValueChangeEvent event) {
Item item = deploymentTable.getItem(event.getProperty().getValue()); // the value of the property is the itemId of the table entry
String deploymentId = (String) item.getItemProperty("id").getValue();
mainSplitPanel.setSecondComponent(new DeploymentDetailPanel(deploymentId));
// Update URL
ExplorerApplication.getCurrent().setCurrentUriFragment(
new UriFragment(DeploymentNavigationHandler.DEPLOYMENT_URI_PART, deploymentId));
}
});
......@@ -66,5 +81,11 @@ public class DeploymentPage extends ManagementPage {
deploymentTable.setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
}
public void selectDeployment(int index) {
if (deploymentTable.getContainerDataSource().size() > index) {
deploymentTable.select(index);
deploymentTable.setCurrentPageFirstItemId(index);
}
}
}
......@@ -17,13 +17,14 @@ import org.activiti.explorer.ExplorerApplication;
import org.activiti.explorer.Images;
import org.activiti.explorer.data.LazyLoadingContainer;
import org.activiti.explorer.data.LazyLoadingQuery;
import org.activiti.explorer.navigation.TaskNavigationHandler;
import org.activiti.explorer.navigation.UriFragment;
import org.activiti.explorer.ui.util.ThemeImageColumnGenerator;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.ui.Table;
import com.vaadin.ui.themes.Reindeer;
/**
......@@ -68,9 +69,12 @@ public class TaskInboxPage extends TaskPage {
Item item = taskTable.getItem(event.getProperty().getValue()); // the value of the property is the itemId of the table entry
String taskId = (String) item.getItemProperty("id").getValue();
mainSplitPanel.setSecondComponent(new TaskDetailPanel(taskId));
UriFragment taskFragment = new UriFragment(TaskNavigationHandler.TASK_URI_PART, taskId);
taskFragment.addParameter("category", TaskNavigationHandler.CATEGORY_INBOX);
// TODO: add utility to set fragments based on page/id's
ExplorerApplication.getCurrent().getUriFragmentUtility().setFragment("tasks/" + taskId, false);
ExplorerApplication.getCurrent().setCurrentUriFragment(taskFragment);
}
});
......
/* Licensed 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.activiti.explorer.util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
/**
* @author 'Frederik Heremans'
*/
public class UriUtility {
private static final String PARAMETER_SEPARATOR = "&";
private static final String QUERY_STRING_SEPARATOR = "?";
private static final String NAME_VALUE_SEPARATOR = "=";
private static final String URL_PART_SEPARATOR = "/";
/**
* Get path fragments. eg: "/task/inbox/123" will return a list with three
* values: "task", "inbox" and "123" in that order.
*/
public static List<String> getFragmentParts(String url) {
if (url != null) {
List<String> parts = new ArrayList<String>();
String[] partsArray = url.split(URL_PART_SEPARATOR);
for (String part : partsArray) {
if (part.length() > 0) {
parts.add(part);
}
}
return parts;
}
return null;
}
/**
* Extracts the query parameters from the given url fragment.
*/
public static String extractQueryString(String fragment) {
if (fragment != null) {
int firstIndex = fragment.indexOf(QUERY_STRING_SEPARATOR);
if (firstIndex >= 0) {
return fragment.substring(firstIndex);
}
}
return null;
}
/**
* Extracts uri from the given url fragment, without the query params.
*/
public static String extractUri(String fragment) {
if (fragment != null) {
int firstIndex = fragment.indexOf(QUERY_STRING_SEPARATOR);
if (firstIndex >= 0) {
return fragment.substring(0, firstIndex);
} else {
// No query string present, use full fragment
return fragment;
}
}
return null;
}
/**
* Parses the parameters from the given url query string. When no encoding is
* passed, default UTF-8 is used. Based on the implementation in Commons
* httpclient UrlEncodedUtils.
*/
public static Map<String, String> parseQueryParameters(String queryString, String encoding) {
Map<String, String> parameters = new LinkedHashMap<String, String>();
if (queryString != null) {
// Remove '?' if present at beginning of query-string
if(queryString.startsWith(QUERY_STRING_SEPARATOR)) {
queryString = queryString.substring(1);
}
Scanner scanner = new Scanner(queryString);
scanner.useDelimiter(PARAMETER_SEPARATOR);
while (scanner.hasNext()) {
final String[] nameValue = scanner.next().split(NAME_VALUE_SEPARATOR);
if (nameValue.length == 0 || nameValue.length > 2)
throw new IllegalArgumentException("bad parameter");
final String name = decode(nameValue[0], encoding);
String value = null;
if (nameValue.length == 2) {
value = decode(nameValue[1], encoding);
}
parameters.put(name, value);
}
}
return parameters;
}
/**
* Gets a valid query-string based on the given parameters.
*/
public static String getQueryString(Map<String, String> parameters) {
StringBuilder result = new StringBuilder();
if (parameters != null) {
for (Entry<String, String> param : parameters.entrySet()) {
final String encodedName = encode(param.getKey(), null);
final String value = param.getValue();
final String encodedValue = value != null ? encode(value, null) : "";
if (result.length() > 0) {
result.append(PARAMETER_SEPARATOR);
} else {
result.append(QUERY_STRING_SEPARATOR);
}
result.append(encodedName);
result.append(NAME_VALUE_SEPARATOR);
result.append(encodedValue);
}
}
return result.toString();
}
/**
* Gets full path based on the given parts.
*/
public static String getPath(List<String> parts) {
if (parts != null) {
StringBuilder result = new StringBuilder();
for (String part : parts) {
if(result.length() > 0) {
result.append(URL_PART_SEPARATOR);
}
result.append(part);
}
return result.toString();
}
return "";
}
private static String decode(final String content, final String encoding) {
try {
return URLDecoder.decode(content, encoding != null ? encoding : "UTF-8");
} catch (UnsupportedEncodingException problem) {
throw new IllegalArgumentException(problem);
}
}
private static String encode(final String content, final String encoding) {
try {
return URLEncoder.encode(content, encoding != null ? encoding : "UTF-8");
} catch (UnsupportedEncodingException problem) {
throw new IllegalArgumentException(problem);
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册