Package: DbgpXmlEntityParser

DbgpXmlEntityParser

nameinstructionbranchcomplexitylinemethod
DbgpXmlEntityParser()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getChildElements(Element)
M: 37 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
getEncodedValue(Element)
M: 31 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
getFromChildOrAttr(Element, String)
M: 17 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
parseBreakpoint(Element)
M: 154 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 29 C: 0
0%
M: 1 C: 0
0%
parseFeature(Element)
M: 19 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
parseProperty(Element)
M: 159 C: 0
0%
M: 24 C: 0
0%
M: 13 C: 0
0%
M: 42 C: 0
0%
M: 1 C: 0
0%
parseSession(Element)
M: 39 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
parseStackLevel(Element)
M: 65 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 16 C: 0
0%
M: 1 C: 0
0%
parseStatus(Element)
M: 51 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
parseURI(String)
M: 88 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%~
3: * org.overture.ide.debug
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.ide.debug.core.dbgp.internal.utils;
23:
24: import java.net.URI;
25: import java.net.URISyntaxException;
26: import java.util.List;
27: import java.util.Vector;
28:
29: import org.overture.ide.debug.core.IDebugConstants;
30: import org.overture.ide.debug.core.VdmDebugPlugin;
31: import org.overture.ide.debug.core.dbgp.IDbgpProperty;
32: import org.overture.ide.debug.core.dbgp.IDbgpSessionInfo;
33: import org.overture.ide.debug.core.dbgp.IDbgpStatus;
34: import org.overture.ide.debug.core.dbgp.IDbgpStatusInterpreterThreadState;
35: import org.overture.ide.debug.core.dbgp.breakpoints.IDbgpBreakpoint;
36: import org.overture.ide.debug.core.dbgp.exceptions.DbgpException;
37: import org.overture.ide.debug.core.dbgp.exceptions.DbgpProtocolException;
38: import org.overture.ide.debug.core.dbgp.internal.DbgpFeature;
39: import org.overture.ide.debug.core.dbgp.internal.DbgpProperty;
40: import org.overture.ide.debug.core.dbgp.internal.DbgpSessionInfo;
41: import org.overture.ide.debug.core.dbgp.internal.DbgpStackLevel;
42: import org.overture.ide.debug.core.dbgp.internal.DbgpStatus;
43: import org.overture.ide.debug.core.dbgp.internal.DbgpStatusInterpreterThreadState;
44: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpCallBreakpoint;
45: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpConditionalBreakpoint;
46: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpExceptionBreakpoint;
47: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpLineBreakpoint;
48: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpReturnBreakpoint;
49: import org.overture.ide.debug.core.dbgp.internal.breakpoints.DbgpWatchBreakpoint;
50: import org.w3c.dom.Element;
51: import org.w3c.dom.Node;
52: import org.w3c.dom.NodeList;
53: //import org.eclipse.dltk.compiler.util.Util;
54: //import org.eclipse.dltk.core.DLTKCore;
55: import org.eclipse.osgi.util.NLS;
56:
57: public class DbgpXmlEntityParser extends DbgpXmlParser
58: {
59:         private static final IDbgpProperty[] NO_CHILDREN = new IDbgpProperty[0];
60:
61:         private static final String ENCODING_NONE = "none"; //$NON-NLS-1$
62:         private static final String ENCODING_BASE64 = "base64"; //$NON-NLS-1$
63:
64:         public static final String TAG_PROPERTY = "property"; //$NON-NLS-1$
65:
66:         protected DbgpXmlEntityParser()
67:         {
68:
69:         }
70:
71:         private static final String ATTR_LEVEL = "level"; //$NON-NLS-1$
72:         private static final String ATTR_CMDBEGIN = "cmdbegin"; //$NON-NLS-1$
73:         private static final String ATTR_CMDEND = "cmdend"; //$NON-NLS-1$
74:         private static final String ATTR_LINENO = "lineno"; //$NON-NLS-1$
75:         private static final String ATTR_FILENAME = "filename"; //$NON-NLS-1$
76:         private static final String ATTR_WHERE = "where"; //$NON-NLS-1$
77:
78:         public static DbgpStackLevel parseStackLevel(Element element)
79:                         throws DbgpException
80:         {
81:                 int level = Integer.parseInt(element.getAttribute(ATTR_LEVEL));
82:
83:                 String cmdBegin = element.getAttribute(ATTR_CMDBEGIN);
84:                 String cmdEnd = element.getAttribute(ATTR_CMDEND);
85:
86:                 int beginLine = -1;
87:                 int beginColumn = -1;
88:                 int endLine = -1;
89:                 int endColumn = -1;
90:•                if (cmdBegin.length() != 0 && cmdEnd.length() != 0)
91:                 {
92:                         beginLine = parseLine(cmdBegin);
93:                         beginColumn = parseColumn(cmdBegin);
94:                         endLine = parseLine(cmdEnd);
95:                         endColumn = parseColumn(cmdEnd);
96:                 }
97:
98:                 int lineNumber = Integer.parseInt(element.getAttribute(ATTR_LINENO));
99:
100:                 /**
101:                  * TODO Check ATTR_TYPE who knows when. According to the http://xdebug.org/docs-dbgp.php#stack-get
102:                  * <code>Valid values are "file" or "eval"</code>, but Tcl debugger also sends "source" and "console".
103:                  */
104:                 final URI fileUri = parseURI(element.getAttribute(ATTR_FILENAME));
105:
106:                 final String where = element.getAttribute(ATTR_WHERE);
107:
108:                 return new DbgpStackLevel(fileUri, where, level, lineNumber, beginLine, beginColumn, endLine, endColumn);
109:         }
110:
111:         private static final String FILE_SCHEME_PREFIX = IDebugConstants.FILE_SCHEME
112:                         + ":///"; //$NON-NLS-1$
113:
114:         private static URI parseURI(String fileName)
115:         {
116:                 /*
117:                  * ActiveState python debugger on windows sends URI as "file:///C|/path/to/file.py" we need to convert it.
118:                  */
119:•                if (fileName.startsWith(FILE_SCHEME_PREFIX))
120:                 {
121:                         final int pos = FILE_SCHEME_PREFIX.length();
122:•                        if (fileName.length() > pos + 3)
123:                         {
124:•                                if (Character.isLetter(fileName.charAt(pos))
125:•                                                && fileName.charAt(pos + 1) == '|'
126:•                                                && fileName.charAt(pos + 2) == '/')
127:                                 {
128:                                         fileName = fileName.substring(0, pos + 1) + ':'
129:                                                         + fileName.substring(pos + 2);
130:                                 }
131:                         }
132:                 }
133:                 try
134:                 {
135:                         return URI.create(fileName);
136:                 } catch (IllegalArgumentException e)
137:                 {
138:•                        if (VdmDebugPlugin.DEBUG)
139:                         {
140:                                 e.printStackTrace();
141:                         }
142:                 }
143:                 try
144:                 {
145:                         return new URI(IDebugConstants.UNKNOWN_SCHEME, Util.EMPTY_STRING, Util.EMPTY_STRING, fileName);
146:                 } catch (URISyntaxException e)
147:                 {
148:•                        if (VdmDebugPlugin.DEBUG)
149:                         {
150:                                 e.printStackTrace();
151:                         }
152:                 }
153:                 try
154:                 {
155:                         return new URI(IDebugConstants.UNKNOWN_SCHEME, Util.EMPTY_STRING, Util.EMPTY_STRING, "unknown");//$NON-NLS-1$
156:                 } catch (URISyntaxException e)
157:                 {
158:                         throw new IllegalArgumentException(e.getMessage());
159:                 }
160:         }
161:
162:         private static final String ATTR_FEATURE_NAME = "feature_name"; //$NON-NLS-1$
163:         private static final String ATTR_SUPPORTED = "supported"; //$NON-NLS-1$
164:
165:         public static DbgpFeature parseFeature(Element element)
166:                         throws DbgpProtocolException
167:         {
168:                 String name = element.getAttribute(ATTR_FEATURE_NAME);
169:                 boolean supported = makeBoolean(element.getAttribute(ATTR_SUPPORTED));
170:                 String value = parseContent(element);
171:                 return new DbgpFeature(supported, name, value);
172:         }
173:
174:         private static final String ATTR_NAME = "name"; //$NON-NLS-1$
175:         private static final String ATTR_FULLNAME = "fullname"; //$NON-NLS-1$
176:         private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
177:         private static final String ATTR_CHILDREN = "children"; //$NON-NLS-1$
178:         private static final String ATTR_NUMCHILDREN = "numchildren"; //$NON-NLS-1$
179:         private static final String ATTR_CONSTANT = "constant"; //$NON-NLS-1$
180:         private static final String ATTR_KEY = "key"; //$NON-NLS-1$
181:         private static final String ATTR_PAGE = "page"; //$NON-NLS-1$
182:         private static final String ATTR_PAGE_SIZE = "pagesize"; //$NON-NLS-1$
183:         private static final String ATTR_ADDRESS = "address"; //$NON-NLS-1$
184:
185:         public static IDbgpProperty parseProperty(Element property)
186:         {
187:                 /*
188:                  * attributes: name, fullname, type, children, numchildren, constant, encoding, size, key, address
189:                  */
190:
191:                 // may exist as an attribute of the property or as child element
192:                 final String name = getFromChildOrAttr(property, ATTR_NAME);
193:                 final String fullName = getFromChildOrAttr(property, ATTR_FULLNAME);
194:
195:                 final String type = property.getAttribute(ATTR_TYPE);
196:
197:                 // hasChildren
198:                 boolean hasChildren = false;
199:•                if (property.hasAttribute(ATTR_CHILDREN))
200:                 {
201:                         hasChildren = makeBoolean(property.getAttribute(ATTR_CHILDREN));
202:                 }
203:
204:                 // Children count
205:                 int childrenCount = -1;
206:•                if (property.hasAttribute(ATTR_NUMCHILDREN))
207:                 {
208:                         childrenCount = Integer.parseInt(property.getAttribute(ATTR_NUMCHILDREN));
209:                 }
210:
211:                 // Page
212:                 int page = 0;
213:•                if (property.hasAttribute(ATTR_PAGE))
214:                 {
215:                         page = Integer.parseInt(property.getAttribute(ATTR_PAGE));
216:                 }
217:
218:                 // Page Size
219:                 int pagesize = -1;
220:•                if (property.hasAttribute(ATTR_PAGE_SIZE))
221:                 {
222:                         pagesize = Integer.parseInt(property.getAttribute(ATTR_PAGE_SIZE));
223:                 }
224:
225:                 // Constant
226:                 boolean constant = false;
227:•                if (property.hasAttribute(ATTR_CONSTANT))
228:                 {
229:                         constant = makeBoolean(property.getAttribute(ATTR_CONSTANT));
230:                 }
231:
232:                 // Key
233:                 String key = null;
234:•                if (property.hasAttribute(ATTR_KEY))
235:                 {
236:                         key = property.getAttribute(ATTR_KEY);
237:                 }
238:
239:                 // memory address
240:                 String address = null;
241:•                if (property.hasAttribute(ATTR_ADDRESS))
242:                 {
243:                         address = property.getAttribute(ATTR_ADDRESS);
244:                 }
245:
246:                 // Value
247:                 String value = ""; //$NON-NLS-1$
248:
249:                 NodeList list = property.getElementsByTagName("value"); //$NON-NLS-1$
250:•                if (list.getLength() == 0)
251:                 {
252:                         value = getEncodedValue(property);
253:                 } else
254:                 {
255:                         value = getEncodedValue((Element) list.item(0));
256:                 }
257:
258:                 // Children
259:                 IDbgpProperty[] availableChildren = NO_CHILDREN;
260:•                if (hasChildren)
261:                 {
262:                         // final NodeList children = property
263:                         // .getElementsByTagName(TAG_PROPERTY);
264:                         List<Element> children = getChildElements(property);
265:
266:                         final int length = children.size();// children.getLength();
267:•                        if (length > 0)
268:                         {
269:                                 availableChildren = new IDbgpProperty[length];
270:•                                for (int i = 0; i < length; ++i)
271:                                 {
272:                                         Element child = (Element) children.get(i);
273:                                         availableChildren[i] = parseProperty(child);
274:                                 }
275:                         }
276:                 }
277:
278:•                if (childrenCount < 0)
279:                 {
280:                         childrenCount = availableChildren.length;
281:                 }
282:
283:                 return new DbgpProperty(name, fullName, type, value, childrenCount, hasChildren, constant, key, address, availableChildren, page, pagesize);
284:         }
285:
286:         private static final String ATTR_REASON = "reason"; //$NON-NLS-1$
287:         private static final String ATTR_STATUS = "status"; //$NON-NLS-1$
288:
289:         private static final String ELEM_INTERNAL = "internal";
290:         private static final String ATTR_THREAD_ID = "threadId";
291:         private static final String ATTR_THREAD_NAME = "threadName";
292:         private static final String ATTR_THREAD_STATE = "threadState";
293:
294:         public static IDbgpStatus parseStatus(Element element)
295:                         throws DbgpProtocolException
296:         {
297:
298:                 String status = element.getAttribute(ATTR_STATUS);
299:                 String reason = element.getAttribute(ATTR_REASON);
300:
301:                 IDbgpStatusInterpreterThreadState interpreterThreadState = null;
302:
303:                 NodeList internalElements = element.getElementsByTagName(ELEM_INTERNAL);
304:
305:•                if (internalElements.getLength() > 0
306:•                                && internalElements.item(0).getNodeType() == Node.ELEMENT_NODE)
307:                 {
308:                         Element internalElement = (Element) internalElements.item(0);
309:
310:                         int threadId = Integer.parseInt(internalElement.getAttribute(ATTR_THREAD_ID));
311:                         String name = internalElement.getAttribute(ATTR_THREAD_NAME);
312:                         String tState = internalElement.getAttribute(ATTR_THREAD_STATE);
313:                         interpreterThreadState = DbgpStatusInterpreterThreadState.parse(threadId, name, tState);
314:                 }
315:
316:                 return DbgpStatus.parse(status, reason, interpreterThreadState);
317:         }
318:
319:         private static final String LINE_BREAKPOINT = "line"; //$NON-NLS-1$
320:         private static final String CALL_BREAKPOINT = "call"; //$NON-NLS-1$
321:         private static final String RETURN_BREAKPOINT = "return"; //$NON-NLS-1$
322:         private static final String EXCEPTION_BREAKPOINT = "exception"; //$NON-NLS-1$
323:         private static final String CONDITIONAL_BREAKPOINT = "conditional"; //$NON-NLS-1$
324:         private static final String WATCH_BREAKPOINT = "watch"; //$NON-NLS-1$
325:
326:         private static final String ATTR_ID = "id"; //$NON-NLS-1$
327:         private static final String ATTR_STATE = "state"; //$NON-NLS-1$
328:         private static final String ATTR_HIT_COUNT = "hit_count"; //$NON-NLS-1$
329:         private static final String ATTR_HIT_VALUE = "hit_value"; //$NON-NLS-1$
330:         private static final String ATTR_HIT_CONDITION = "hit_condition"; //$NON-NLS-1$
331:         private static final String ATTR_LINE = "line"; //$NON-NLS-1$
332:         private static final String ATTR_FUNCTION = "function"; //$NON-NLS-1$
333:         private static final String ATTR_EXCEPTION = "exception"; //$NON-NLS-1$
334:         private static final String ATTR_EXPRESSION = "expression"; //$NON-NLS-1$
335:
336:         private static List<Element> getChildElements(Element node)
337:
338:         {
339:
340:                 List<Element> elements = new Vector<Element>();
341:
342:                 NodeList childs = node.getChildNodes();
343:
344:•                for (int j = 0; j < childs.getLength(); j++)
345:
346:                 {
347:
348:                         // Node cNode = childs.item(j);
349:
350:•                        if (childs.item(j).getNodeName().equals(TAG_PROPERTY)
351:•                                        && childs.item(j).getNodeType() == Node.ELEMENT_NODE)
352:
353:                         {
354:
355:                                 elements.add((Element) childs.item(j));
356:
357:                         }
358:
359:                 }
360:
361:                 return elements;
362:
363:         }
364:
365:         public static IDbgpBreakpoint parseBreakpoint(Element element)
366:         {
367:                 // ActiveState Tcl
368:
369:                 // ActiveState Python
370:                 // <response xmlns="urn:debugger_protocol_v1" command="breakpoint_get"
371:                 // transaction_id="1">
372:                 // <breakpoint id="1"
373:                 // type="line"
374:                 // filename="c:\distrib\dbgp\test\test1.py"
375:                 // lineno="8"
376:                 // state="enabled"
377:                 // temporary="0">
378:                 // </breakpoint>
379:                 // </response>
380:
381:                 String type = element.getAttribute(ATTR_TYPE);
382:
383:                 String id = element.getAttribute(ATTR_ID);
384:                 boolean enabled = element.getAttribute(ATTR_STATE).equals("enabled"); //$NON-NLS-1$
385:
386:                 // not all dbgp implementations have these
387:                 int hitCount = getIntAttribute(element, ATTR_HIT_COUNT, 0);
388:                 int hitValue = getIntAttribute(element, ATTR_HIT_VALUE, 0);
389:                 String hitCondition = getStringAttribute(element, ATTR_HIT_CONDITION);
390:
391:•                if (type.equals(LINE_BREAKPOINT))
392:                 {
393:                         String fileName = element.getAttribute(ATTR_FILENAME);
394:
395:                         // ActiveState's dbgp implementation is slightly inconsistent
396:                         String lineno = element.getAttribute(ATTR_LINENO);
397:•                        if ("".equals(lineno)) { //$NON-NLS-1$
398:                                 lineno = element.getAttribute(ATTR_LINE);
399:                         }
400:
401:                         int lineNumber = Integer.parseInt(lineno);
402:                         return new DbgpLineBreakpoint(id, enabled, hitValue, hitCount, hitCondition, fileName, lineNumber);
403:•                } else if (type.equals(CALL_BREAKPOINT))
404:                 {
405:                         String function = element.getAttribute(ATTR_FUNCTION);
406:                         return new DbgpCallBreakpoint(id, enabled, hitValue, hitCount, hitCondition, function);
407:•                } else if (type.equals(RETURN_BREAKPOINT))
408:                 {
409:                         String function = element.getAttribute(ATTR_FUNCTION);
410:                         return new DbgpReturnBreakpoint(id, enabled, hitValue, hitCount, hitCondition, function);
411:•                } else if (type.equals(EXCEPTION_BREAKPOINT))
412:                 {
413:                         String exception = element.getAttribute(ATTR_EXCEPTION);
414:                         return new DbgpExceptionBreakpoint(id, enabled, hitValue, hitCount, hitCondition, exception);
415:•                } else if (type.equals(CONDITIONAL_BREAKPOINT))
416:                 {
417:                         String expression = element.getAttribute(ATTR_EXPRESSION);
418:                         return new DbgpConditionalBreakpoint(id, enabled, hitValue, hitCount, hitCondition, expression);
419:•                } else if (type.equals(WATCH_BREAKPOINT))
420:                 {
421:                         String expression = element.getAttribute(ATTR_EXPRESSION);
422:                         return new DbgpWatchBreakpoint(id, enabled, hitValue, hitCount, hitCondition, expression);
423:                 }
424:
425:                 return null;
426:         }
427:
428:         private static final String ATTR_APPID = "appid"; //$NON-NLS-1$
429:         private static final String ATTR_IDEKEY = "idekey"; //$NON-NLS-1$
430:         private static final String ATTR_SESSION = "session"; //$NON-NLS-1$
431:         private static final String ATTR_THREAD = "thread"; //$NON-NLS-1$
432:         private static final String ATTR_PARENT = "parent"; //$NON-NLS-1$
433:         private static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$
434:
435:         public static IDbgpSessionInfo parseSession(Element element)
436:         {
437:                 String appId = element.getAttribute(ATTR_APPID);
438:                 String ideKey = element.getAttribute(ATTR_IDEKEY);
439:                 String session = element.getAttribute(ATTR_SESSION);
440:                 String threadId = element.getAttribute(ATTR_THREAD);
441:                 String parentId = element.getAttribute(ATTR_PARENT);
442:                 String language = element.getAttribute(ATTR_LANGUAGE);
443:                 DbgpException error = DbgpXmlParser.checkError(element);
444:                 return new DbgpSessionInfo(appId, ideKey, session, threadId, parentId, language, null, error);
445:         }
446:
447:         protected static String getFromChildOrAttr(Element property, String name)
448:         {
449:                 NodeList list = property.getElementsByTagName(name);
450:
451:•                if (list.getLength() == 0)
452:                 {
453:                         return property.getAttribute(name);
454:                 }
455:
456:                 /*
457:                  * this may or may not need to be base64 decoded - need to see output from an ActiveState's python debugging
458:                  * session to determine. gotta love protocol changes that have made their way back into the published spec
459:                  */
460:                 return getEncodedValue((Element) list.item(0));
461:         }
462:
463:         private static final String ATTR_ENCODING = "encoding"; //$NON-NLS-1$
464:
465:         protected static String getEncodedValue(Element element)
466:         {
467:                 String encoding = ENCODING_NONE;
468:•                if (element.hasAttribute(ATTR_ENCODING))
469:                 {
470:                         encoding = element.getAttribute(ATTR_ENCODING);
471:                 }
472:
473:•                if (ENCODING_NONE.equals(encoding))
474:                 {
475:                         return parseContent(element);
476:                 }
477:
478:•                if (ENCODING_BASE64.equals(encoding))
479:                 {
480:                         return parseBase64Content(element);
481:                 }
482:
483:                 throw new AssertionError(NLS.bind("invalidEncoding", encoding));
484:         }
485:
486: }