blob: 26075541c4001fddbfc8821a3182a3cf69113f98 [file] [log] [blame]
Richard S. Hallaf656a02009-06-11 16:07:20 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package aQute.shell.runtime;
20
21import java.io.*;
22import java.lang.reflect.*;
23import java.util.*;
24
25import org.osgi.service.command.*;
26
27public class CommandSessionImpl implements CommandSession, Converter {
28 String COLUMN = "%-20s %s\n";
29 InputStream in;
30 PrintStream out;
31 PrintStream err;
32 CommandShellImpl service;
33 Map<Object, Object> variables = new HashMap<Object, Object>();
34
35 CommandSessionImpl(CommandShellImpl service, InputStream in,
36 PrintStream out, PrintStream err) {
37 this.service = service;
38 this.in = in;
39 this.out = out;
40 this.err = err;
41 }
42
43 public void close() {
44 }
45
46 public Object execute(CharSequence commandline) throws Exception {
47 assert service != null;
48 assert service.threadIO != null;
49
50 Closure impl = new Closure(this, null, commandline);
51 Object result = impl.execute(this, null);
52 return result;
53 }
54
55 public InputStream getKeybord() {
56 return in;
57 }
58
59 public Object get(String name) {
60 if (variables != null && variables.containsKey(name))
61 return variables.get(name);
62
63 return service.get(name);
64 }
65
66 public void put(String name, Object value) {
67 variables.put(name, value);
68 }
69
70 public PrintStream getConsole() {
71 return out;
72 }
73
74
75 @SuppressWarnings("unchecked")
76 public
77 CharSequence format(Object target, int level, Converter escape ) throws Exception {
78 if (target == null)
79 return "null";
80
81 if (target instanceof CharSequence )
82 return (CharSequence) target;
83
84 for (Converter c : service.converters) {
85 CharSequence s = c.format(target, level, this);
86 if (s != null)
87 return s;
88 }
89
90 if (target.getClass().isArray()) {
91 if ( target.getClass().getComponentType().isPrimitive()) {
92 if ( target.getClass().getComponentType() == boolean.class )
93 return Arrays.toString((boolean[]) target);
94 else if ( target.getClass().getComponentType() == byte.class )
95 return Arrays.toString((byte[]) target);
96 else if ( target.getClass().getComponentType() == short.class )
97 return Arrays.toString((short[]) target);
98 else if ( target.getClass().getComponentType() == int.class )
99 return Arrays.toString((int[]) target);
100 else if ( target.getClass().getComponentType() == long.class )
101 return Arrays.toString((long[]) target);
102 else if ( target.getClass().getComponentType() == float.class )
103 return Arrays.toString((float[]) target);
104 else if ( target.getClass().getComponentType() == double.class )
105 return Arrays.toString((double[]) target);
106 else if ( target.getClass().getComponentType() == char.class )
107 return Arrays.toString((char[]) target);
108 }
109 target = Arrays.asList((Object[]) target);
110 }
111 if (target instanceof Collection) {
112 if (level == Converter.INSPECT) {
113 StringBuilder sb = new StringBuilder();
114 Collection<?> c = (Collection<?>) target;
115 for (Object o : c) {
116 sb.append(format(o, level + 1, this));
117 sb.append("\n");
118 }
119 return sb;
120 } else if (level == Converter.LINE) {
121 StringBuilder sb = new StringBuilder();
122 String del = "[";
123 Collection<?> c = (Collection<?>) target;
124 for (Object o : c) {
125 sb.append(del);
126 sb.append(format(o, level + 1, this));
127 del = ", ";
128 }
129 sb.append("]");
130 return sb;
131 }
132 }
133 if ( target instanceof Dictionary ) {
134 Map<Object,Object> result = new HashMap<Object,Object>();
135 for ( Enumeration e = ((Dictionary)target).keys(); e.hasMoreElements(); ) {
136 Object key = e.nextElement();
137 result.put(key, ((Dictionary)target).get(key));
138 }
139 target = result;
140 }
141 if (target instanceof Map) {
142 if (level == Converter.INSPECT) {
143 StringBuilder sb = new StringBuilder();
144 Map<?,?> c = (Map<?,?>) target;
145 for (Map.Entry<?,?> entry : c.entrySet()) {
146 CharSequence key = format(entry.getKey(), level + 1, this);
147 sb.append(key);
148 for ( int i=key.length(); i<20; i++ )
149 sb.append(' ');
150 sb.append(format(entry.getValue(), level + 1, this));
151 sb.append("\n");
152 }
153 return sb;
154 } else if (level == Converter.LINE) {
155 StringBuilder sb = new StringBuilder();
156 String del = "[";
157 Map<?,?> c = (Map<?,?>) target;
158 for (Map.Entry<?,?> entry : c.entrySet()) {
159 sb.append(del);
160 sb.append(format(entry, level + 1,this));
161 del = ", ";
162 }
163 sb.append("]");
164 return sb;
165 }
166 }
167 if (level == Converter.INSPECT)
168 return inspect(target);
169 else
170 return target.toString();
171 }
172
173 CharSequence inspect(Object b) {
174 boolean found = false;
175 Formatter f = new Formatter();
176 Method methods[] = b.getClass().getMethods();
177 for (Method m : methods) {
178 try {
179 String name = m.getName();
180 if (m.getName().startsWith("get")
181 && !m.getName().equals("getClass")
182 && m.getParameterTypes().length == 0
183 && Modifier.isPublic(m.getModifiers())) {
184 found = true;
185 name = name.substring(3);
186 m.setAccessible(true);
187 Object value = m.invoke(b, (Object[]) null);
188 f.format(COLUMN, name, format(value, Converter.LINE, this));
189 }
190 } catch (IllegalAccessException e) {
191 // Ignore
192 } catch (Exception e) {
193 e.printStackTrace();
194 }
195 }
196 if (found)
197 return (StringBuilder) f.out();
198 else
199 return b.toString();
200 }
201
202
203 public Object convert(Class<?> desiredType, Object in) {
204 return service.convert(desiredType, in);
205 }
206
207 public CharSequence format(Object result, int inspect) {
208 try {
209 return format(result,inspect,this);
210 } catch(Exception e ) {
211 return "<can not format " + result + ":" + e;
212 }
213 }
214
215}