Wiki source code of Click to Debug
Version 11.1 by Chuck Hill on 2008/12/15 15:27
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | == What It Is == | ||
2 | |||
3 | Click to Debug is a [[Click to Open]] extension that allows you to toggle binding debugging from the UI while your applicaiton is running. | ||
4 | |||
5 | == What You Need == | ||
6 | |||
7 | See the [[What You Need>>Click to Open||anchor="What You Need"]] section of the Click to Open documentation if you are not already using Click to to Open. | ||
8 | |||
9 | == Getting Set Up == | ||
10 | |||
11 | See the [[Getting Set Up>>Click to Open||anchor="Getting Set Up"]] section of the Click to Open documentation if you are not already using Click to to Open. | ||
12 | |||
13 | Add this line to the ##Properties## file in your application: | ||
14 | |||
15 | {{code}} | ||
16 | |||
17 | ognl.debugSupport=true | ||
18 | |||
19 | {{/code}} | ||
20 | |||
21 | === Add Support to Application === | ||
22 | |||
23 | If your Application.java class extends (directly or indirectly) Wonder's ERXApplication, you can skip this step. Otherwise, add this to your Application() constructor, or a method that runs before requests are processed:: | ||
24 | |||
25 | {{code value="java"}} | ||
26 | |||
27 | NSNotificationCenter.defaultCenter().addObserver(this, | ||
28 | ERXSelectorUtilities.notificationSelector("applicationDidHandleRequest"), | ||
29 | WOApplication.ApplicationDidDispatchRequestNotification, null); | ||
30 | |||
31 | {{/code}} | ||
32 | |||
33 | Then add this method to handle this notification: | ||
34 | |||
35 | {{code value="java"}} | ||
36 | |||
37 | /** | ||
38 | * When request is finished, we remove the context from thread local storage. | ||
39 | * | ||
40 | * @see #createContextForRequest(WORequest) | ||
41 | * @param n notification | ||
42 | */ | ||
43 | public void applicationDidHandleRequest(NSNotification n) { | ||
44 | ERXWOContext.setCurrentContext(null); | ||
45 | ERXThreadStorage.removeValueForKey(ERXWOContext.CONTEXT_DICTIONARY_KEY); | ||
46 | } | ||
47 | |||
48 | {{/code}} | ||
49 | |||
50 | The next part is a method that sets ERXWOContext.currentContext() when a request is dispatched: | ||
51 | |||
52 | {{code value="java"}} | ||
53 | |||
54 | /** | ||
55 | * When a context is created we push it into thread local storage. | ||
56 | * | ||
57 | * @see #applicationDidHandleRequest(NSNotification) | ||
58 | * @param request the request | ||
59 | * @return the newly created context | ||
60 | */ | ||
61 | public WOContext createContextForRequest(WORequest request) { | ||
62 | WOContext context = super.createContextForRequest(request); | ||
63 | // We only want to push in the context the first time it is | ||
64 | // created, ie we don't want to lose the current context | ||
65 | // when we create a context for an error page. | ||
66 | if (ERXWOContext.currentContext() == null) { | ||
67 | ERXWOContext.setCurrentContext(context); | ||
68 | } | ||
69 | return context; | ||
70 | } | ||
71 | |||
72 | {{/code}} | ||
73 | |||
74 | And finally, add this code to support Click to Debug: | ||
75 | |||
76 | {{code value="java"}} | ||
77 | |||
78 | protected void _debugValueForDeclarationNamed(WOComponent component, String verb, String aDeclarationName, String aDeclarationType, String aBindingName, String anAssociationDescription, Object aValue) { | ||
79 | if (aValue instanceof String) { | ||
80 | StringBuffer stringbuffer = new StringBuffer(((String) aValue).length() + 2); | ||
81 | stringbuffer.append('"'); | ||
82 | stringbuffer.append(aValue); | ||
83 | stringbuffer.append('"'); | ||
84 | aValue = stringbuffer; | ||
85 | } | ||
86 | if (aDeclarationName.startsWith("_")) { | ||
87 | aDeclarationName = "[inline]"; | ||
88 | } | ||
89 | |||
90 | StringBuffer sb = new StringBuffer(); | ||
91 | |||
92 | //NSArray<WOComponent> componentPath = ERXWOContext._componentPath(ERXWOContext.currentContext()); | ||
93 | //componentPath.lastObject() | ||
94 | //WOComponent lastComponent = ERXWOContext.currentContext().component(); | ||
95 | String lastComponentName = component.name().replaceFirst(".*\\.", ""); | ||
96 | sb.append(lastComponentName); | ||
97 | |||
98 | sb.append(verb); | ||
99 | |||
100 | if (!aDeclarationName.startsWith("_")) { | ||
101 | sb.append(aDeclarationName); | ||
102 | sb.append(":"); | ||
103 | } | ||
104 | sb.append(aDeclarationType); | ||
105 | |||
106 | sb.append(" { "); | ||
107 | sb.append(aBindingName); | ||
108 | sb.append("="); | ||
109 | |||
110 | String valueStr = aValue != null ? aValue.toString() : "null"; | ||
111 | if (anAssociationDescription.startsWith("class ")) { | ||
112 | sb.append(valueStr); | ||
113 | sb.append("; }"); | ||
114 | } | ||
115 | else { | ||
116 | sb.append(anAssociationDescription); | ||
117 | sb.append("; } value "); | ||
118 | sb.append(valueStr); | ||
119 | } | ||
120 | |||
121 | NSLog.debug.appendln(sb.toString()); | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * The set of component names that have binding debug enabled | ||
126 | */ | ||
127 | private NSMutableSet<String> _debugComponents = new NSMutableSet<String>(); | ||
128 | |||
129 | /** | ||
130 | * Little bit better binding debug output than the original. | ||
131 | */ | ||
132 | @Override | ||
133 | public void logTakeValueForDeclarationNamed(String aDeclarationName, String aDeclarationType, String aBindingName, String anAssociationDescription, Object aValue) { | ||
134 | WOComponent component = ERXWOContext.currentContext().component(); | ||
135 | if (component.parent() != null) { | ||
136 | component = component.parent(); | ||
137 | } | ||
138 | _debugValueForDeclarationNamed(component, " ==> ", aDeclarationName, aDeclarationType, aBindingName, anAssociationDescription, aValue); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * Little bit better binding debug output than the original. | ||
143 | */ | ||
144 | @Override | ||
145 | public void logSetValueForDeclarationNamed(String aDeclarationName, String aDeclarationType, String aBindingName, String anAssociationDescription, Object aValue) { | ||
146 | WOComponent component = ERXWOContext.currentContext().component(); | ||
147 | if (component.parent() != null) { | ||
148 | component = component.parent(); | ||
149 | } | ||
150 | _debugValueForDeclarationNamed(component, " <== ", aDeclarationName, aDeclarationType, aBindingName, anAssociationDescription, aValue); | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * Turns on/off binding debugging for the given component. Binding debugging requires using the WOOgnl | ||
155 | * template parser and setting ognl.debugSupport=true. | ||
156 | * | ||
157 | * @param debugEnabled whether or not to enable debugging | ||
158 | * @param componentName the component name to enable debugging for | ||
159 | */ | ||
160 | public void setDebugEnabledForComponent(boolean debugEnabled, String componentName) { | ||
161 | if (debugEnabled) { | ||
162 | _debugComponents.addObject(componentName); | ||
163 | } | ||
164 | else { | ||
165 | _debugComponents.removeObject(componentName); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * Returns whether or not binding debugging is enabled for the given component | ||
171 | * | ||
172 | * @param componentName the component name | ||
173 | * @return whether or not binding debugging is enabled for the given componen | ||
174 | */ | ||
175 | public boolean debugEnabledForComponent(String componentName) { | ||
176 | return _debugComponents.containsObject(componentName); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * Turns off binding debugging for all components. | ||
181 | */ | ||
182 | public void clearDebugEnabledForAllComponents() { | ||
183 | _debugComponents.removeAllObjects(); | ||
184 | } | ||
185 | |||
186 | {{/code}} | ||
187 | |||
188 | == Using Click to Debug == | ||
189 | |||
190 | Coming soon | ||
191 | |||
192 | == == |