/* * eXist Open Source Native XML Database * Copyright (C) 2009 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: PropertyGet.java 11737 2010-05-02 21:25:21Z ixitar $ */ package org.exist.debuggee.dbgp.packets; import org.apache.mina.core.session.IoSession; import org.exist.xquery.Variable; import org.exist.xquery.XQueryContext; import org.exist.xquery.XPathException; import org.exist.xquery.value.*; import org.exist.storage.serializers.Serializer; import org.xml.sax.SAXException; /** * @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a> * */ public class PropertyGet extends Command { /** * -d stack depth (optional, debugger engine should assume zero if not provided) */ private int stackDepth = 0; /** * -c context id (optional, retrieved by context-names, debugger engine should assume zero if not provided) */ private int contextID = 0; /** * -n property long name (required) */ private String nameLong; /** * -m max data size to retrieve (optional) */ private Integer maxDataSize = null; /** * -p data page (property_get, property_value: optional for arrays, hashes, objects, etc.; property_set: not required; debugger engine should assume zero if not provided) */ private String dataPage = null; /** * -k property key as retrieved in a property element, optional, used for property_get of children and property_value, required if it was provided by the debugger engine. */ private String propertyKey = null; /** * -a property address as retrieved in a property element, optional, used for property_set/value */ private String propertyAddress = null; private Variable variable; public PropertyGet(IoSession session, String args) { super(session, args); } protected void setArgument(String arg, String val) { if (arg.equals("d")) stackDepth = Integer.parseInt(val); else if (arg.equals("c")) contextID = Integer.parseInt(val); else if (arg.equals("n")) nameLong = val; else if (arg.equals("m")) maxDataSize = Integer.parseInt(val); else if (arg.equals("p")) dataPage = val; else if (arg.equals("k")) propertyKey = val; else if (arg.equals("a")) propertyAddress = val; else super.setArgument(arg, val); } /* (non-Javadoc) * @see org.exist.debuggee.dgbp.packets.Command#exec() */ @Override public void exec() { variable = getJoint().getVariable(nameLong); } public byte[] responseBytes() { if (variable == null) return errorBytes("property_get"); StringBuilder responce = new StringBuilder(); responce.append("<response command=\"property_get\" transaction_id=\""); responce.append(transactionID); responce.append("\">"); responce.append(getPropertyString(variable, getJoint().getContext())); responce.append("</response>"); return responce.toString().getBytes(); } protected static StringBuilder getPropertyString(Variable variable, XQueryContext context) { Sequence value = variable.getValue(); Serializer serializer = context.getBroker().getSerializer(); serializer.reset(); try { StringBuilder property = new StringBuilder(); if (value.hasOne()) { String strVal = getPropertyValue(value.itemAt(0), serializer); String type = Type.subTypeOf(value.getItemType(), Type.NODE) ? "node" : Type.getTypeName(value.getItemType()); property.append("<property name=\""); property.append(variable.getQName().toString()); property.append("\" fullname=\""); property.append(variable.getQName().toString()); property.append("\" type=\""); property.append(type); property.append("\" size=\""); property.append(strVal.length()); property.append("\" encoding=\"none\">"); property.append(strVal); property.append("</property>"); } else { property.append("<property name=\""); property.append(variable.getQName().toString()); property.append("\" fullname=\""); property.append(variable.getQName().toString()); property.append("\" type=\"array\" children=\"true\" numchildren=\""); property.append(value.getItemCount()); property.append("\">"); int idx = 0; for (SequenceIterator si = value.iterate(); si.hasNext(); idx++) { Item item = si.nextItem(); String strVal = getPropertyValue(item, serializer); String type = Type.subTypeOf(value.getItemType(), Type.NODE) ? "xs:string" : Type.getTypeName(value.getItemType()); property.append("<property name=\""); property.append(idx); property.append("\" type=\""); property.append(type); property.append("\" size=\""); property.append(strVal.length()); property.append("\" encoding=\"none\">"); property.append(strVal); property.append("</property>"); } property.append("</property>"); } return property; } catch (SAXException e) { e.printStackTrace(); } catch (XPathException e) { e.printStackTrace(); } return null; } protected static String getTypeString(Variable variable) { if (!variable.isInitialized()) return "uninitialized"; return Type.getTypeName(variable.getType()); } protected static String getPropertyValue(Item item, Serializer serializer) throws SAXException, XPathException { if (Type.subTypeOf(item.getType(), Type.NODE)) { return "<![CDATA[" + serializer.serialize((NodeValue) item) + "]]>"; } else { return item.getStringValue(); } } public byte[] commandBytes() { String command = "property_get" + " -i "+transactionID+ " -n "+nameLong+ " -d "+String.valueOf(stackDepth)+ " -c "+String.valueOf(contextID); if (maxDataSize != null) command += " -m "+String.valueOf(maxDataSize); if (dataPage != null) command += " -p "+String.valueOf(dataPage); if (propertyKey != null) command += " -k "+propertyKey; if (propertyAddress != null) command += " -a "+propertyAddress; return command.getBytes(); } }