use of lucee.runtime.converter.WDDXConverter in project Lucee by lucee.
the class Props method callCFCMetaData.
private void callCFCMetaData(PageContext pc, Component cfc, int format) throws IOException, PageException, ConverterException {
ComponentSpecificAccess cw = new ComponentSpecificAccess(Component.ACCESS_REMOTE, cfc);
ComponentScope scope = cw.getComponentScope();
Struct udfs = new StructImpl(), sctUDF, sctArg;
Array arrArg;
Iterator<Object> it = scope.valueIterator();
Object v;
UDF udf;
FunctionArgument[] args;
while (it.hasNext()) {
v = it.next();
// UDF
if (v instanceof UDF) {
udf = (UDF) v;
sctUDF = new StructImpl();
arrArg = new ArrayImpl();
udfs.setEL(udf.getFunctionName(), sctUDF);
args = udf.getFunctionArguments();
for (int i = 0; i < args.length; i++) {
sctArg = new StructImpl();
arrArg.appendEL(sctArg);
sctArg.setEL(KeyConstants._name, args[i].getName().getString());
sctArg.setEL(KeyConstants._type, args[i].getTypeAsString());
sctArg.setEL(KeyConstants._required, args[i].isRequired());
if (!StringUtil.isEmpty(args[i].getHint()))
sctArg.setEL(KeyConstants._hint, args[i].getHint());
}
sctUDF.set(KeyConstants._arguments, arrArg);
sctUDF.set(KeyConstants._returntype, udf.getReturnTypeAsString());
}
}
Struct rtn = new StructImpl();
rtn.set(KeyConstants._functions, udfs);
rtn.set(ACCEPT_ARG_COLL_FORMATS, "cfml,json");
InputStream is;
Charset cs = null;
// WDDX
if (UDF.RETURN_FORMAT_WDDX == format) {
WDDXConverter converter = new WDDXConverter(pc.getTimeZone(), false, false);
converter.setTimeZone(pc.getTimeZone());
String str = converter.serialize(rtn);
cs = getCharset(pc);
is = new ByteArrayInputStream(str.getBytes(cs));
} else // JSON
if (UDF.RETURN_FORMAT_JSON == format) {
boolean byColumn = false;
cs = getCharset(pc);
JSONConverter converter = new JSONConverter(false, cs);
String str = converter.serialize(pc, rtn, byColumn);
is = new ByteArrayInputStream(str.getBytes(cs));
} else // CFML
if (UDF.RETURN_FORMAT_SERIALIZE == format) {
ScriptConverter converter = new ScriptConverter(false);
String str = converter.serialize(rtn);
cs = getCharset(pc);
is = new ByteArrayInputStream(str.getBytes(cs));
} else // XML
if (UDF.RETURN_FORMAT_XML == format) {
XMLConverter converter = new XMLConverter(pc.getTimeZone(), false);
converter.setTimeZone(pc.getTimeZone());
String str = converter.serialize(rtn);
cs = getCharset(pc);
is = new ByteArrayInputStream(str.getBytes(cs));
} else // Plain
if (UDF.RETURN_FORMAT_PLAIN == format) {
String str = Caster.toString(rtn);
cs = getCharset(pc);
is = new ByteArrayInputStream(str.getBytes(cs));
} else // Java
if (UDF.RETURN_FORMAT_JAVA == format) {
byte[] bytes = JavaConverter.serializeAsBinary(rtn);
is = new ByteArrayInputStream(bytes);
} else
throw new IOException("invalid format defintion:" + format);
OutputStream os = null;
try {
os = pc.getResponseStream();
setFormat(pc.getHttpServletResponse(), format, cs);
IOUtil.copy(is, os, false, false);
} finally {
IOUtil.flushEL(os);
IOUtil.closeEL(os);
((PageContextImpl) pc).getRootOut().setClosed(true);
}
}
use of lucee.runtime.converter.WDDXConverter in project Lucee by lucee.
the class XMLConfigAdmin method storageSet.
public void storageSet(Config config, String key, Object value) throws ConverterException, IOException, SecurityException {
checkWriteAccess();
Resource storageDir = getStoragDir(config);
Resource storage = storageDir.getRealResource(key + ".wddx");
WDDXConverter converter = new WDDXConverter(config.getTimeZone(), true, true);
String wddx = converter.serialize(value);
IOUtil.write(storage, wddx, "UTF-8", false);
}
use of lucee.runtime.converter.WDDXConverter in project Lucee by lucee.
the class DumpUtil method toDumpData.
public static DumpData toDumpData(Object o, PageContext pageContext, int maxlevel, DumpProperties props) {
if (maxlevel < 0)
return MAX_LEVEL_REACHED;
// null
if (o == null) {
DumpTable table = new DumpTable("null", "#ff6600", "#ffcc99", "#000000");
table.appendRow(new DumpRow(0, new SimpleDumpData("Empty:null")));
return table;
}
if (o instanceof DumpData) {
return ((DumpData) o);
}
// Date
if (o instanceof Date) {
return new DateTimeImpl((Date) o).toDumpData(pageContext, maxlevel, props);
}
// Calendar
if (o instanceof Calendar) {
Calendar c = (Calendar) o;
SimpleDateFormat df = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss zz", Locale.ENGLISH);
df.setTimeZone(c.getTimeZone());
DumpTable table = new DumpTable("date", "#ff9900", "#ffcc00", "#000000");
table.setTitle("java.util.Calendar");
table.appendRow(1, new SimpleDumpData("Timezone"), new SimpleDumpData(TimeZoneUtil.toString(c.getTimeZone())));
table.appendRow(1, new SimpleDumpData("Time"), new SimpleDumpData(df.format(c.getTime())));
return table;
}
// StringBuffer
if (o instanceof StringBuffer) {
DumpTable dt = (DumpTable) toDumpData(o.toString(), pageContext, maxlevel, props);
if (StringUtil.isEmpty(dt.getTitle()))
dt.setTitle(Caster.toClassName(o));
return dt;
}
// StringBuilder
if (o instanceof StringBuilder) {
DumpTable dt = (DumpTable) toDumpData(o.toString(), pageContext, maxlevel, props);
if (StringUtil.isEmpty(dt.getTitle()))
dt.setTitle(Caster.toClassName(o));
return dt;
}
// String
if (o instanceof String) {
String str = (String) o;
if (str.trim().startsWith("<wddxPacket ")) {
try {
WDDXConverter converter = new WDDXConverter(pageContext.getTimeZone(), false, true);
converter.setTimeZone(pageContext.getTimeZone());
Object rst = converter.deserialize(str, false);
DumpData data = toDumpData(rst, pageContext, maxlevel, props);
DumpTable table = new DumpTable("string", "#cc9999", "#ffffff", "#000000");
table.setTitle("WDDX");
table.appendRow(1, new SimpleDumpData("encoded"), data);
table.appendRow(1, new SimpleDumpData("raw"), new SimpleDumpData(str));
return table;
} catch (Exception e) {
// this dump entry is optional, so if it is not possible to create the decoded wddx entry, we simply don't do it
}
}
DumpTable table = new DumpTable("string", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("string"), new SimpleDumpData(str));
return table;
}
// Character
if (o instanceof Character) {
DumpTable table = new DumpTable("character", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("character"), new SimpleDumpData(o.toString()));
return table;
}
// Number
if (o instanceof Number) {
DumpTable table = new DumpTable("numeric", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("number"), new SimpleDumpData(Caster.toString(((Number) o))));
return table;
}
// Charset
if (o instanceof Charset) {
DumpTable table = new DumpTable("charset", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("charset"), new SimpleDumpData(((Charset) o).name()));
return table;
}
// CharSet
if (o instanceof CharSet) {
DumpTable table = new DumpTable("charset", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("charset"), new SimpleDumpData(((CharSet) o).name()));
return table;
}
// Locale
if (o instanceof Locale) {
Locale l = (Locale) o;
Locale env = ThreadLocalPageContext.getLocale();
DumpTable table = new DumpTable("locale", "#ff6600", "#ffcc99", "#000000");
table.setTitle("Locale " + LocaleFactory.getDisplayName(l));
table.appendRow(1, new SimpleDumpData("Code (ISO-3166)"), new SimpleDumpData(l.toString()));
table.appendRow(1, new SimpleDumpData("Country"), new SimpleDumpData(l.getDisplayCountry(env)));
table.appendRow(1, new SimpleDumpData("Language"), new SimpleDumpData(l.getDisplayLanguage(env)));
return table;
}
// TimeZone
if (o instanceof TimeZone) {
DumpTable table = new DumpTable("numeric", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("TimeZone"), new SimpleDumpData(TimeZoneUtil.toString(((TimeZone) o))));
return table;
}
// Boolean
if (o instanceof Boolean) {
DumpTable table = new DumpTable("boolean", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("boolean"), new SimpleDumpData(((Boolean) o).booleanValue()));
return table;
}
// File
if (o instanceof File) {
DumpTable table = new DumpTable("file", "#ffcc00", "#ffff66", "#000000");
table.appendRow(1, new SimpleDumpData("File"), new SimpleDumpData(o.toString()));
return table;
}
// Cookie
if (o instanceof Cookie) {
Cookie c = (Cookie) o;
DumpTable table = new DumpTable("Cookie", "#979EAA", "#DEE9FB", "#000000");
table.setTitle("Cookie (" + c.getClass().getName() + ")");
table.appendRow(1, new SimpleDumpData("name"), new SimpleDumpData(c.getName()));
table.appendRow(1, new SimpleDumpData("value"), new SimpleDumpData(c.getValue()));
table.appendRow(1, new SimpleDumpData("path"), new SimpleDumpData(c.getPath()));
table.appendRow(1, new SimpleDumpData("secure"), new SimpleDumpData(c.getSecure()));
table.appendRow(1, new SimpleDumpData("maxAge"), new SimpleDumpData(c.getMaxAge()));
table.appendRow(1, new SimpleDumpData("version"), new SimpleDumpData(c.getVersion()));
table.appendRow(1, new SimpleDumpData("domain"), new SimpleDumpData(c.getDomain()));
table.appendRow(1, new SimpleDumpData("httpOnly"), new SimpleDumpData(CookieImpl.isHTTPOnly(c)));
table.appendRow(1, new SimpleDumpData("comment"), new SimpleDumpData(c.getComment()));
return table;
}
// Resource
if (o instanceof Resource) {
DumpTable table = new DumpTable("resource", "#ffcc00", "#ffff66", "#000000");
table.appendRow(1, new SimpleDumpData("Resource"), new SimpleDumpData(o.toString()));
return table;
}
// byte[]
if (o instanceof byte[]) {
byte[] bytes = (byte[]) o;
int max = 5000;
DumpTable table = new DumpTable("array", "#ff9900", "#ffcc00", "#000000");
table.setTitle("Native Array (" + Caster.toClassName(o) + ")");
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < bytes.length; i++) {
if (i != 0)
sb.append(",");
sb.append(bytes[i]);
if (i == max) {
sb.append(", ...truncated");
break;
}
}
sb.append("]");
table.appendRow(1, new SimpleDumpData("Raw" + (bytes.length < max ? "" : " (truncated)")), new SimpleDumpData(sb.toString()));
if (bytes.length < max) {
// base64
table.appendRow(1, new SimpleDumpData("Base64 Encoded"), new SimpleDumpData(Base64Coder.encode(bytes)));
/*try {
table.appendRow(1,new SimpleDumpData("CFML expression"),new SimpleDumpData("evaluateJava('"+JavaConverter.serialize(bytes)+"')"));
}
catch (IOException e) {}*/
}
return table;
}
// Collection.Key
if (o instanceof Collection.Key) {
Collection.Key key = (Collection.Key) o;
DumpTable table = new DumpTable("string", "#ff6600", "#ffcc99", "#000000");
table.appendRow(1, new SimpleDumpData("Collection.Key"), new SimpleDumpData(key.getString()));
return table;
}
String id = "" + IDGenerator.intId();
String refid = ThreadLocalDump.get(o);
if (refid != null) {
DumpTable table = new DumpTable("ref", "#ffffff", "#cccccc", "#000000");
table.appendRow(1, new SimpleDumpData("Reference"), new SimpleDumpData(refid));
table.setRef(refid);
return setId(id, table);
}
ThreadLocalDump.set(o, id);
try {
int top = props.getMaxlevel();
// Printable
if (o instanceof Dumpable) {
return setId(id, ((Dumpable) o).toDumpData(pageContext, maxlevel, props));
}
// Map
if (o instanceof Map) {
Map map = (Map) o;
Iterator it = map.keySet().iterator();
DumpTable table = new DumpTable("struct", "#ff9900", "#ffcc00", "#000000");
table.setTitle("Map (" + Caster.toClassName(o) + ")");
while (it.hasNext()) {
Object next = it.next();
table.appendRow(1, toDumpData(next, pageContext, maxlevel, props), toDumpData(map.get(next), pageContext, maxlevel, props));
}
return setId(id, table);
}
// List
if (o instanceof List) {
List list = (List) o;
ListIterator it = list.listIterator();
DumpTable table = new DumpTable("array", "#ff9900", "#ffcc00", "#000000");
table.setTitle("Array (List)");
if (list.size() > top)
table.setComment("Rows: " + list.size() + " (showing top " + top + ")");
int i = 0;
while (it.hasNext() && i++ < top) {
table.appendRow(1, new SimpleDumpData(it.nextIndex() + 1), toDumpData(it.next(), pageContext, maxlevel, props));
}
return setId(id, table);
}
// Set
if (o instanceof Set) {
Set set = (Set) o;
Iterator it = set.iterator();
DumpTable table = new DumpTable("array", "#ff9900", "#ffcc00", "#000000");
table.setTitle("Set (" + set.getClass().getName() + ")");
int i = 0;
while (it.hasNext() && i++ < top) {
table.appendRow(1, toDumpData(it.next(), pageContext, maxlevel, props));
}
return setId(id, table);
}
// Resultset
if (o instanceof ResultSet) {
try {
DumpData dd = new QueryImpl((ResultSet) o, "query", pageContext.getTimeZone()).toDumpData(pageContext, maxlevel, props);
if (dd instanceof DumpTable)
((DumpTable) dd).setTitle(Caster.toClassName(o));
return setId(id, dd);
} catch (PageException e) {
}
}
// Enumeration
if (o instanceof Enumeration) {
Enumeration e = (Enumeration) o;
DumpTable table = new DumpTable("enumeration", "#ff9900", "#ffcc00", "#000000");
table.setTitle("Enumeration");
int i = 0;
while (e.hasMoreElements() && i++ < top) {
table.appendRow(0, toDumpData(e.nextElement(), pageContext, maxlevel, props));
}
return setId(id, table);
}
// Object[]
if (Decision.isNativeArray(o)) {
Array arr;
try {
arr = Caster.toArray(o);
DumpTable htmlBox = new DumpTable("array", "#ff9900", "#ffcc00", "#000000");
htmlBox.setTitle("Native Array (" + Caster.toClassName(o) + ")");
int length = arr.size();
for (int i = 1; i <= length; i++) {
Object ox = null;
try {
ox = arr.getE(i);
} catch (Exception e) {
}
htmlBox.appendRow(1, new SimpleDumpData(i), toDumpData(ox, pageContext, maxlevel, props));
}
return setId(id, htmlBox);
} catch (PageException e) {
return setId(id, new SimpleDumpData(""));
}
}
// Node
if (o instanceof Node) {
return setId(id, XMLCaster.toDumpData((Node) o, pageContext, maxlevel, props));
}
// ObjectWrap
if (o instanceof ObjectWrap) {
maxlevel++;
return setId(id, toDumpData(((ObjectWrap) o).getEmbededObject(null), pageContext, maxlevel, props));
}
// NodeList
if (o instanceof NodeList) {
NodeList list = (NodeList) o;
int len = list.getLength();
DumpTable table = new DumpTable("xml", "#cc9999", "#ffffff", "#000000");
for (int i = 0; i < len; i++) {
table.appendRow(1, new SimpleDumpData(i), toDumpData(list.item(i), pageContext, maxlevel, props));
}
return setId(id, table);
}
// AttributeMap
if (o instanceof NamedNodeMap) {
NamedNodeMap attr = (NamedNodeMap) o;
int len = attr.getLength();
DumpTable dt = new DumpTable("array", "#ff9900", "#ffcc00", "#000000");
dt.setTitle("NamedNodeMap (" + Caster.toClassName(o) + ")");
for (int i = 0; i < len; i++) {
dt.appendRow(1, new SimpleDumpData(i), toDumpData(attr.item(i), pageContext, maxlevel, props));
}
return setId(id, dt);
}
// HttpSession
if (o instanceof HttpSession) {
HttpSession hs = (HttpSession) o;
Enumeration e = hs.getAttributeNames();
DumpTable htmlBox = new DumpTable("httpsession", "#9999ff", "#ccccff", "#000000");
htmlBox.setTitle("HttpSession");
while (e.hasMoreElements()) {
String key = e.nextElement().toString();
htmlBox.appendRow(1, new SimpleDumpData(key), toDumpData(hs.getAttribute(key), pageContext, maxlevel, props));
}
return setId(id, htmlBox);
}
if (o instanceof Pojo) {
DumpTable table = new DumpTable(o.getClass().getName(), "#ff99cc", "#ffccff", "#000000");
Class clazz = o.getClass();
if (o instanceof Class)
clazz = (Class) o;
String fullClassName = clazz.getName();
int pos = fullClassName.lastIndexOf('.');
String className = pos == -1 ? fullClassName : fullClassName.substring(pos + 1);
table.setTitle("Java Bean - " + className + " (" + fullClassName + ")");
table.appendRow(3, new SimpleDumpData("Property Name"), new SimpleDumpData("Value"));
// collect the properties
Method[] methods = clazz.getMethods();
String propName;
Object value;
String exName = null;
String exValue = null;
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (Object.class == method.getDeclaringClass())
continue;
propName = method.getName();
if (propName.startsWith("get") && method.getParameterTypes().length == 0) {
propName = propName.substring(3);
value = null;
try {
value = method.invoke(o, new Object[0]);
if (exName == null && value instanceof String && ((String) value).length() < 20) {
exName = propName;
exValue = value.toString();
}
} catch (Throwable t) {
ExceptionUtil.rethrowIfNecessary(t);
value = "not able to retrieve the data:" + t.getMessage();
}
table.appendRow(0, new SimpleDumpData(propName), toDumpData(value, pageContext, maxlevel, props));
}
}
if (exName == null) {
exName = "LastName";
exValue = "Sorglos";
}
table.setComment("JavaBeans are reusable software components for Java." + "\nThey are classes that encapsulate many objects into a single object (the bean)." + "\nThey allow access to properties using getter and setter methods or directly.");
return setId(id, table);
}
// reflect
// else {
DumpTable table = new DumpTable(o.getClass().getName(), "#6289a3", "#dee3e9", "#000000");
Class clazz = o.getClass();
if (o instanceof Class)
clazz = (Class) o;
String fullClassName = clazz.getName();
int pos = fullClassName.lastIndexOf('.');
String className = pos == -1 ? fullClassName : fullClassName.substring(pos + 1);
table.setTitle(className);
table.appendRow(1, new SimpleDumpData("class"), new SimpleDumpData(fullClassName));
// Fields
Field[] fields = clazz.getFields();
DumpTable fieldDump = new DumpTable("#6289a3", "#dee3e9", "#000000");
fieldDump.appendRow(-1, new SimpleDumpData("name"), new SimpleDumpData("pattern"), new SimpleDumpData("value"));
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
DumpData value;
try {
// print.out(o+":"+maxlevel);
value = new SimpleDumpData(Caster.toString(field.get(o), ""));
} catch (Exception e) {
value = new SimpleDumpData("");
}
fieldDump.appendRow(0, new SimpleDumpData(field.getName()), new SimpleDumpData(field.toString()), value);
}
if (fields.length > 0)
table.appendRow(1, new SimpleDumpData("fields"), fieldDump);
// Constructors
Constructor[] constructors = clazz.getConstructors();
DumpTable constrDump = new DumpTable("#6289a3", "#dee3e9", "#000000");
constrDump.appendRow(-1, new SimpleDumpData("interface"), new SimpleDumpData("exceptions"));
for (int i = 0; i < constructors.length; i++) {
Constructor constr = constructors[i];
// exceptions
StringBuilder sbExp = new StringBuilder();
Class[] exceptions = constr.getExceptionTypes();
for (int p = 0; p < exceptions.length; p++) {
if (p > 0)
sbExp.append("\n");
sbExp.append(Caster.toClassName(exceptions[p]));
}
// parameters
StringBuilder sbParams = new StringBuilder("<init>");
sbParams.append('(');
Class[] parameters = constr.getParameterTypes();
for (int p = 0; p < parameters.length; p++) {
if (p > 0)
sbParams.append(", ");
sbParams.append(Caster.toClassName(parameters[p]));
}
sbParams.append(')');
constrDump.appendRow(0, new SimpleDumpData(sbParams.toString()), new SimpleDumpData(sbExp.toString()));
}
if (constructors.length > 0)
table.appendRow(1, new SimpleDumpData("constructors"), constrDump);
// Methods
StringBuilder objMethods = new StringBuilder();
Method[] methods = clazz.getMethods();
DumpTable methDump = new DumpTable("#6289a3", "#dee3e9", "#000000");
methDump.appendRow(-1, new SimpleDumpData("return"), new SimpleDumpData("interface"), new SimpleDumpData("exceptions"));
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (Object.class == method.getDeclaringClass()) {
if (objMethods.length() > 0)
objMethods.append(", ");
objMethods.append(method.getName());
continue;
}
// exceptions
StringBuilder sbExp = new StringBuilder();
Class[] exceptions = method.getExceptionTypes();
for (int p = 0; p < exceptions.length; p++) {
if (p > 0)
sbExp.append("\n");
sbExp.append(Caster.toClassName(exceptions[p]));
}
// parameters
StringBuilder sbParams = new StringBuilder(method.getName());
sbParams.append('(');
Class[] parameters = method.getParameterTypes();
for (int p = 0; p < parameters.length; p++) {
if (p > 0)
sbParams.append(", ");
sbParams.append(Caster.toClassName(parameters[p]));
}
sbParams.append(')');
methDump.appendRow(0, new SimpleDumpData(Caster.toClassName(method.getReturnType())), new SimpleDumpData(sbParams.toString()), new SimpleDumpData(sbExp.toString()));
}
if (methods.length > 0)
table.appendRow(1, new SimpleDumpData("methods"), methDump);
DumpTable inherited = new DumpTable("#6289a3", "#dee3e9", "#000000");
inherited.appendRow(7, new SimpleDumpData("Methods inherited from java.lang.Object"));
inherited.appendRow(0, new SimpleDumpData(objMethods.toString()));
table.appendRow(1, new SimpleDumpData(""), inherited);
// Bundle Info
ClassLoader cl = clazz.getClassLoader();
if (cl instanceof BundleClassLoader) {
BundleClassLoader bcl = (BundleClassLoader) cl;
Bundle b = bcl.getBundle();
Struct sct = new StructImpl();
sct.setEL(KeyConstants._id, b.getBundleId());
sct.setEL(KeyConstants._name, b.getSymbolicName());
sct.setEL("location", b.getLocation());
sct.setEL(KeyConstants._version, b.getVersion().toString());
DumpTable bd = new DumpTable("#6289a3", "#dee3e9", "#000000");
bd.appendRow(1, new SimpleDumpData("id"), new SimpleDumpData(b.getBundleId()));
bd.appendRow(1, new SimpleDumpData("symbolic-name"), new SimpleDumpData(b.getSymbolicName()));
bd.appendRow(1, new SimpleDumpData("version"), new SimpleDumpData(b.getVersion().toString()));
bd.appendRow(1, new SimpleDumpData("location"), new SimpleDumpData(b.getLocation()));
requiredBundles(bd, b);
table.appendRow(1, new SimpleDumpData("bundle-info"), bd);
}
return setId(id, table);
// }
} finally {
ThreadLocalDump.remove(o);
}
}
Aggregations