Java tutorial
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.ocsoft.rosetto.models.base.elements.values; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import org.apache.commons.lang3.StringUtils; import org.ocsoft.rosetto.contexts.base.Rosetto; import org.ocsoft.rosetto.models.base.elements.RosettoValue; import org.ocsoft.rosetto.models.base.elements.ValueType; import org.ocsoft.rosetto.models.system.Parser; import org.ocsoft.rosetto.models.system.Scope; import org.ocsoft.rosetto.system.exceptions.NotConvertibleException; import org.ocsoft.rosetto.utils.base.TextUtils; import org.ocsoft.rosetto.utils.base.Values; /** * ?????????????.<br> * Rosetto??????????ListValue???.<br> * ?????????????.<br> * <br> * (foo=10 bar=100 2 6 a=1 9 3)<br> * <br> * Rosetto?????????.<br> * <br> * Map {foo=10, bar=100, a=1}<br> * List (2,6,9,3)<br> * <br> * ???????????????????????????.<br> * ??????????.<br> * [size (a=1 b=2 c=3)] => 0 * @author tohhy */ public class ListValue implements RosettoValue { private static final long serialVersionUID = -5778537199758610111L; public static final ListValue EMPTY = new ListValue(new LinkedList<RosettoValue>(), new TreeMap<String, RosettoValue>()); /** * ?.<br> * Lisp?????LinkedList?. */ private final LinkedList<RosettoValue> list; /** * ?.<br> * ???????TreeMap?. */ private final TreeMap<String, RosettoValue> map; /** * ?????????HashedList??. * @param args ?? */ public static ListValue createFromString(String args) { if (args == null) throw new IllegalArgumentException("?null??"); List<RosettoValue> list = new ArrayList<RosettoValue>(); Map<String, RosettoValue> map = new HashMap<String, RosettoValue>(); //??????? //?????????????? List<String> splited = Rosetto.getParser().splitElements(args); Parser parser = Rosetto.getParser(); for (String str : splited) { int equalPosition = str.indexOf("="); if (equalPosition == -1) { list.add(parser.parseElement(TextUtils.removeDoubleQuote(str))); } else { String key = str.substring(0, equalPosition); String value = TextUtils.removeDoubleQuote(str.substring(equalPosition + 1)); map.put(key, parser.parseElement(value)); } } return new ListValue(list, map); } public static ListValue createFromString(String[] args) { List<RosettoValue> list = new LinkedList<RosettoValue>(); Map<String, RosettoValue> map = new HashMap<String, RosettoValue>(); for (String str : args) { int equalPosition = str.indexOf("="); if (equalPosition == -1) { list.add(Values.create(TextUtils.removeDoubleQuote(str))); } else { String key = str.substring(0, equalPosition); String value = TextUtils.removeDoubleQuote(str.substring(equalPosition + 1)); map.put(key, Values.create(value)); } } return new ListValue(list, map); } public static ListValue createFromString(List<String> elements) { List<RosettoValue> list = new ArrayList<RosettoValue>(); Map<String, RosettoValue> map = new HashMap<String, RosettoValue>(); for (String element : elements) { int equalPosition = element.indexOf("="); if (equalPosition == -1) { list.add(Values.create(TextUtils.removeDoubleQuote(element))); } else { String key = element.substring(0, equalPosition); String value = TextUtils.removeDoubleQuote(element.substring(equalPosition + 1)); map.put(key, Values.create(value)); } } return new ListValue(list, map); } public static ListValue createFromValue(List<RosettoValue> list, Map<String, RosettoValue> map) { return new ListValue(new LinkedList<RosettoValue>(list), new HashMap<String, RosettoValue>(map)); } public static ListValue createFromValue(ListValue list) { return new ListValue(new LinkedList<RosettoValue>(list.getList()), new HashMap<String, RosettoValue>(list.getMap())); } private ListValue(List<RosettoValue> list, Map<String, RosettoValue> map) { this.list = (list instanceof LinkedList) ? (LinkedList<RosettoValue>) list : new LinkedList<RosettoValue>(list); this.map = (map instanceof TreeMap) ? (TreeMap<String, RosettoValue>) map : new TreeMap<String, RosettoValue>(map); } public ListValue(List<RosettoValue> list) { this((list instanceof LinkedList) ? (LinkedList<RosettoValue>) list : new LinkedList<RosettoValue>(list), new TreeMap<String, RosettoValue>()); } public ListValue(RosettoValue... values) { this(toList(values)); } public ListValue(String... values) { this(toList(values)); } private static List<RosettoValue> toList(RosettoValue... values) { LinkedList<RosettoValue> list = new LinkedList<RosettoValue>(); for (RosettoValue v : values) list.add(v); return list; } private static List<RosettoValue> toList(String... values) { Parser parser = Rosetto.getParser(); LinkedList<RosettoValue> list = new LinkedList<RosettoValue>(); for (String s : values) list.add(parser.parseElement(s)); return list; } @Override public boolean equals(Object obj) { if (obj instanceof RosettoValue) { return ((RosettoValue) obj).asString().equals(this.asString()); } return false; } @Override public String toString() { return asString(); } /** * ??????????.<br> * ??????.????asString??. */ public String toArgsExpression() { StringBuilder sb = new StringBuilder(); sb.append(StringUtils.join(list, ' ')); int mapLen = map.size(); if (mapLen > 0) sb.append(" "); sb.append(StringUtils.join(map.entrySet(), ' ')); return sb.toString(); } @Override public RosettoValue evaluate(Scope scope) { return this; } /** * ?????????????????. * @return */ public ListValue evaluateChildren(Scope parentScope) { List<RosettoValue> list = new ArrayList<RosettoValue>(); Map<String, RosettoValue> map = new TreeMap<String, RosettoValue>(); for (RosettoValue v : this.list) { if (v instanceof ActionCall) { list.add(((ActionCall) v).evaluate(parentScope)); } else { list.add(v); } } for (Entry<String, RosettoValue> e : this.map.entrySet()) { if (e.getValue() instanceof ActionCall) { map.put(e.getKey(), ((ActionCall) e.getValue()).evaluate(parentScope)); } else { map.put(e.getKey(), e.getValue()); } } return new ListValue(list, map); } /** * ????????. * ????????????????. * ???????????. * ????ActionCall??. * @param func ?? * @return ???? */ public Map<String, RosettoValue> bind(RosettoFunction func, Scope currentScope) { if (func == null) throw new IllegalArgumentException("???null??"); //?? Map<String, RosettoValue> result = new HashMap<String, RosettoValue>(); //???? LinkedList<String> funcArgs = new LinkedList<String>(); //??????????? int requiredArgsCount = 0; //???????? for (String s : func.getArguments()) { int eqIndex = s.indexOf("="); if (eqIndex == -1) { //????????? funcArgs.add(s); //???????? requiredArgsCount++; } else { //???? String key = s.substring(0, eqIndex); RosettoValue value = Values.create(s.substring(eqIndex + 1, s.length())); //? funcArgs.add(key); //??????? result.put(key, value); } } //?????? //?? for (Entry<String, RosettoValue> e : getMap().entrySet()) { //?Entry??funcArgs?????funcArg boolean removed = funcArgs.remove(e.getKey()); //???? if (removed) requiredArgsCount--; //?? result.put(e.getKey(), e.getValue()); } //?? String mutableArg = searchMutableArg(funcArgs); if (mutableArg != null) { //???????? //???????? //??????????-1 if (requiredArgsCount - 1 > getList().size()) { throw new IllegalArgumentException("???????: " + getList().toString() + "|" + func.getArguments()); } //???????????????? //?? List<RosettoValue> margs = new LinkedList<RosettoValue>(); for (int i = 0; i < getList().size(); i++) { RosettoValue v = getList().get(i); if (!funcArgs.isEmpty()) { //???????????pop????????? String farg = funcArgs.pollFirst(); //?????????? if (farg.equals(mutableArg)) { //?????????????? if (!funcArgs.isEmpty()) { throw new IllegalArgumentException("mutable args must be last element"); } //?? margs.add(v); } //???????? result.put(farg, v); } else { //?? margs.add(v); } } //????? if (margs.size() > 0) { //????? String margName = mutableArg.substring(1); //listvalue??? result.put(margName, new ListValue(margs)); } } else { //??????? if (requiredArgsCount > getList().size()) { throw new IllegalArgumentException("???????: " + getList().toString() + "|" + func.getArguments()); } else if (funcArgs.size() < getList().size()) { throw new IllegalArgumentException( "?????: " + getList().toString() + "|" + func.getArguments()); } for (RosettoValue value : getList()) { //????????? if (value.getType() == ValueType.ACTION_CALL) { //ActionCall?????? result.put(funcArgs.pollFirst(), ((ActionCall) value).evaluate(currentScope)); } else { result.put(funcArgs.pollFirst(), value); } } } return result; } public boolean hasMappedValue() { return map.size() > 0; } /** * ??????. */ public boolean containsKey(String key) { return map.containsKey(key); } @Override public RosettoValue first() { return list.getFirst(); } @Override public RosettoValue rest() { if (list.size() == 0 || list.size() == 1) return Values.NULL; if (list.size() == 2) return list.get(1); return new ListValue(list.subList(1, list.size()), map); } @Override public RosettoValue cons(RosettoValue head) { return null; } /** * List?????. */ public RosettoValue getAt(int listIndex) { return list.get(listIndex); } /** * List????. */ @Override public int size() { return list.size(); } /** * ???????. */ public RosettoValue get(String mapKey) { return map.containsKey(mapKey) ? map.get(mapKey) : Values.NULL; } public int optionSize() { return map.size(); } public List<RosettoValue> getList() { return Collections.unmodifiableList(list); } public Map<String, RosettoValue> getMap() { return Collections.unmodifiableMap(map); } /** * ?????. * @return ????????null */ private String searchMutableArg(List<String> args) { String result = null; for (String s : args) { if (s.startsWith("*") && s.length() >= 2) { if (result != null) throw new IllegalArgumentException("multiple mutablearg found"); result = s; } } return result; } @Override public ValueType getType() { return ValueType.LIST; } @Override public Object getValue() { return this; } @Override public String asString() throws NotConvertibleException { return "(" + toArgsExpression() + ")"; } @Override public String asString(String defaultValue) { return "(" + toArgsExpression() + ")"; } @Override public boolean asBool() throws NotConvertibleException { throw new NotConvertibleException(); } @Override public boolean asBool(boolean defaultValue) { return defaultValue; } @Override public int asInt() throws NotConvertibleException { throw new NotConvertibleException(); } @Override public int asInt(int defaultValue) { return defaultValue; } @Override public long asLong() throws NotConvertibleException { throw new NotConvertibleException(); } @Override public long asLong(long defaultValue) { return defaultValue; } @Override public double asDouble() throws NotConvertibleException { throw new NotConvertibleException(); } @Override public double asDouble(double defaultValue) { return defaultValue; } }