/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.core.command; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Iterator; import org.xmind.core.command.arguments.Attributes; import org.xmind.core.command.binary.IBinaryEntry; import org.xmind.core.command.binary.IBinaryStore; import org.xmind.core.internal.command.Logger; import org.xmind.core.internal.command.XMindCommandPlugin; public class Command implements ICommand { private static boolean DEBUGGING = XMindCommandPlugin.isDebugging("/debug"); //$NON-NLS-1$ public static final String XMIND_SCHEME = "xmind"; //$NON-NLS-1$ public static final String XMIND_PROTOCOL = XMIND_SCHEME + ":"; //$NON-NLS-1$ private String source; private String commandName; private Attributes arguments; private String target; private IBinaryStore files; public Command(String source, String commandName) { this(source, commandName, null, null, null); } public Command(String source, String commandName, Attributes arguments, String target, IBinaryStore files) { this.source = source; this.commandName = commandName; if (arguments == null) { this.arguments = new Attributes(); } else { this.arguments = arguments; } this.target = target; this.files = files; } public String getCommandName() { return commandName; } public Attributes getArguments() { return arguments; } public String getArgument(String key) { return arguments.get(key); } public String getSource() { return source; } public String getTarget() { return target; } public IBinaryStore getBinaryStore() { return files; } public IBinaryEntry getBinaryEntry(String entryName) { return files == null ? null : files.getEntry(entryName); } public static Command parseURI(String uriString, IBinaryStore files) { URI uri; try { uri = new URI(uriString); } catch (URISyntaxException e) { Logger.log("Malformed URI: " + uriString, null); //$NON-NLS-1$ return null; } if (!XMIND_SCHEME.equals(uri.getScheme())) { if (DEBUGGING) System.out .println("Not a valid XMind command URI: " + uriString); //$NON-NLS-1$ return null; } return new Command(uri.getHost(), trimPath(uri.getPath()), parseArguments(uri.getRawQuery()), uri.getFragment(), files); } public static Command parseURI(String uriString) { return parseURI(uriString, null); } private static String trimPath(String path) { if (path == null) return path; if (path.startsWith("/")) //$NON-NLS-1$ path = path.substring(1); if (path.endsWith("/")) //$NON-NLS-1$ path = path.substring(0, path.length() - 1); return path; } private static Attributes parseArguments(String query) { if (query == null || "".equals(query)) //$NON-NLS-1$ return new Attributes(); Attributes args = new Attributes(); for (String kv : query.split("&")) { //$NON-NLS-1$ int sep = kv.indexOf('='); if (sep < 0) { args.with(urlDecode(kv), ""); //$NON-NLS-1$ } else { args.with(urlDecode(kv.substring(0, sep)), urlDecode(kv.substring(sep + 1))); } } return args; } private static String urlDecode(String text) { try { return URLDecoder.decode(text, "UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { if (DEBUGGING) { System.err.println("Failed to decode XMind command argument: " //$NON-NLS-1$ + text); e.printStackTrace(); } return text; } } private static String urlEncode(String text) { try { return URLEncoder.encode(text, "UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { if (DEBUGGING) { System.err.println("Failed to encode XMind command argument: " //$NON-NLS-1$ + text); e.printStackTrace(); } return text; } } public String toURI() { return toURI(this); } @Override public String toString() { return toURI(); } public static String toURI(ICommand command) { StringBuffer buf = new StringBuffer(32); buf.append(XMIND_PROTOCOL); buf.append('/'); buf.append('/'); buf.append(command.getSource()); String commandName = command.getCommandName(); if (commandName != null) { if (!commandName.startsWith("/")) { //$NON-NLS-1$ buf.append('/'); } buf.append(commandName); } else { buf.append('/'); } Attributes arguments = command.getArguments(); if (arguments != null && !arguments.isEmpty()) { buf.append('?'); Iterator<String> keys = arguments.keys(); boolean firstArgument = true; while (keys.hasNext()) { String key = keys.next(); String value = arguments.get(key); if (value != null) { if (!firstArgument) { buf.append('&'); } else { firstArgument = false; } buf.append(urlEncode(key)); buf.append('='); buf.append(urlEncode(value)); } } } String target = command.getTarget(); if (target != null) { buf.append('#'); buf.append(target); } return buf.toString(); } }