|
Lines 8-17
Link Here
|
| 8 |
|
8 |
|
| 9 |
package org.eclipse.mylar.internal.sandbox.web; |
9 |
package org.eclipse.mylar.internal.sandbox.web; |
| 10 |
|
10 |
|
| 11 |
import java.util.regex.Matcher; |
11 |
import java.io.IOException; |
| 12 |
import java.util.regex.Pattern; |
12 |
import java.util.List; |
| 13 |
|
13 |
|
|
|
14 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 15 |
import org.eclipse.core.runtime.IStatus; |
| 16 |
import org.eclipse.core.runtime.MultiStatus; |
| 17 |
import org.eclipse.core.runtime.Status; |
| 18 |
import org.eclipse.core.runtime.jobs.Job; |
| 19 |
import org.eclipse.jface.bindings.keys.KeyStroke; |
| 20 |
import org.eclipse.jface.fieldassist.ContentProposalAdapter; |
| 21 |
import org.eclipse.jface.fieldassist.IContentProposal; |
| 22 |
import org.eclipse.jface.fieldassist.IContentProposalProvider; |
| 23 |
import org.eclipse.jface.fieldassist.TextContentAdapter; |
| 14 |
import org.eclipse.jface.wizard.WizardPage; |
24 |
import org.eclipse.jface.wizard.WizardPage; |
|
|
25 |
import org.eclipse.mylar.provisional.tasklist.AbstractQueryHit; |
| 15 |
import org.eclipse.mylar.provisional.tasklist.AbstractRepositoryQuery; |
26 |
import org.eclipse.mylar.provisional.tasklist.AbstractRepositoryQuery; |
| 16 |
import org.eclipse.mylar.provisional.tasklist.MylarTaskListPlugin; |
27 |
import org.eclipse.mylar.provisional.tasklist.MylarTaskListPlugin; |
| 17 |
import org.eclipse.mylar.provisional.tasklist.TaskRepository; |
28 |
import org.eclipse.mylar.provisional.tasklist.TaskRepository; |
|
Lines 25-30
Link Here
|
| 25 |
import org.eclipse.swt.layout.GridLayout; |
36 |
import org.eclipse.swt.layout.GridLayout; |
| 26 |
import org.eclipse.swt.widgets.Button; |
37 |
import org.eclipse.swt.widgets.Button; |
| 27 |
import org.eclipse.swt.widgets.Composite; |
38 |
import org.eclipse.swt.widgets.Composite; |
|
|
39 |
import org.eclipse.swt.widgets.Display; |
| 28 |
import org.eclipse.swt.widgets.Label; |
40 |
import org.eclipse.swt.widgets.Label; |
| 29 |
import org.eclipse.swt.widgets.Table; |
41 |
import org.eclipse.swt.widgets.Table; |
| 30 |
import org.eclipse.swt.widgets.TableColumn; |
42 |
import org.eclipse.swt.widgets.TableColumn; |
|
Lines 56-61
Link Here
|
| 56 |
|
68 |
|
| 57 |
private TaskRepository repository; |
69 |
private TaskRepository repository; |
| 58 |
private WebQuery query; |
70 |
private WebQuery query; |
|
|
71 |
private UpdatePreviewJob updatePreviewJob; |
| 59 |
|
72 |
|
| 60 |
public WebQueryWizardPage(TaskRepository repository) { |
73 |
public WebQueryWizardPage(TaskRepository repository) { |
| 61 |
this(repository, null); |
74 |
this(repository, null); |
|
Lines 97-104
Link Here
|
| 97 |
} |
110 |
} |
| 98 |
}); |
111 |
}); |
| 99 |
queryUrlText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
112 |
queryUrlText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
|
|
113 |
new Label(composite, SWT.NONE); |
| 114 |
|
| 115 |
Label regexpLabel = new Label(composite, SWT.NONE); |
| 116 |
regexpLabel.setText("Regexp:"); |
| 117 |
regexpLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true)); |
| 118 |
|
| 119 |
regexpText = new Text(composite, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.WRAP); |
| 120 |
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); |
| 121 |
gridData.heightHint = 39; |
| 122 |
regexpText.setLayoutData(gridData); |
| 123 |
|
| 124 |
regexpText.addModifyListener(new ModifyListener() { |
| 125 |
public void modifyText(final ModifyEvent e) { |
| 126 |
if(webPage!=null) { |
| 127 |
updatePreview(); |
| 128 |
} |
| 129 |
} |
| 130 |
}); |
| 131 |
|
| 132 |
new ContentProposalAdapter(regexpText, new TextContentAdapter(), |
| 133 |
new RegExpProposalProvider(), KeyStroke.getInstance(SWT.CTRL, ' '), null); |
| 100 |
|
134 |
|
| 101 |
Button preview = new Button(composite, SWT.NONE); |
135 |
Button preview = new Button(composite, SWT.NONE); |
|
|
136 |
preview.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true)); |
| 102 |
preview.setText("Preview"); |
137 |
preview.setText("Preview"); |
| 103 |
preview.addSelectionListener(new SelectionAdapter() { |
138 |
preview.addSelectionListener(new SelectionAdapter() { |
| 104 |
public void widgetSelected(final SelectionEvent e) { |
139 |
public void widgetSelected(final SelectionEvent e) { |
|
Lines 114-140
Link Here
|
| 114 |
taskPrefixText = new Text(composite, SWT.BORDER); |
149 |
taskPrefixText = new Text(composite, SWT.BORDER); |
| 115 |
taskPrefixText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
150 |
taskPrefixText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| 116 |
new Label(composite, SWT.NONE); |
151 |
new Label(composite, SWT.NONE); |
| 117 |
|
|
|
| 118 |
Label regexpLabel = new Label(composite, SWT.NONE); |
| 119 |
regexpLabel.setText("Regexp:"); |
| 120 |
regexpLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true)); |
| 121 |
|
| 122 |
regexpText = new Text(composite, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.WRAP); |
| 123 |
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); |
| 124 |
gridData.heightHint = 39; |
| 125 |
regexpText.setLayoutData(gridData); |
| 126 |
regexpText.addModifyListener(new ModifyListener() { |
| 127 |
public void modifyText(final ModifyEvent e) { |
| 128 |
if(webPage!=null) { |
| 129 |
updatePreview(); |
| 130 |
} |
| 131 |
} |
| 132 |
}); |
| 133 |
|
| 134 |
|
152 |
|
| 135 |
// ContentProposalAdapter adapter = new ContentProposalAdapter(regexpText, new TextContentAdapter(), |
|
|
| 136 |
// new RegExpProposalProvider(), KeyStroke.getInstance(SWT.CTRL, ' '), null); |
| 137 |
|
| 138 |
previewTable = new Table(sashForm, SWT.BORDER); |
153 |
previewTable = new Table(sashForm, SWT.BORDER); |
| 139 |
previewTable.setLinesVisible(true); |
154 |
previewTable.setLinesVisible(true); |
| 140 |
previewTable.setHeaderVisible(true); |
155 |
previewTable.setHeaderVisible(true); |
|
Lines 152-162
Link Here
|
| 152 |
if(query!=null) { |
167 |
if(query!=null) { |
| 153 |
descriptionText.setText(query.getDescription()); |
168 |
descriptionText.setText(query.getDescription()); |
| 154 |
queryUrlText.setText(query.getQueryUrl()); |
169 |
queryUrlText.setText(query.getQueryUrl()); |
| 155 |
taskPrefixText.setText(query.getTaskPrefix()); |
|
|
| 156 |
regexpText.setText(query.getRegexp()); |
170 |
regexpText.setText(query.getRegexp()); |
|
|
171 |
taskPrefixText.setText(query.getTaskPrefix()); |
| 157 |
} |
172 |
} |
| 158 |
new Label(composite, SWT.NONE); |
173 |
sashForm.setWeights(new int[] {141, 172 }); |
| 159 |
sashForm.setWeights(new int[] {123, 166 }); |
|
|
| 160 |
} |
174 |
} |
| 161 |
|
175 |
|
| 162 |
public AbstractRepositoryQuery getQuery() { |
176 |
public AbstractRepositoryQuery getQuery() { |
|
Lines 168-260
Link Here
|
| 168 |
MylarTaskListPlugin.getTaskListManager().getTaskList(), repository.getUrl()); |
182 |
MylarTaskListPlugin.getTaskListManager().getTaskList(), repository.getUrl()); |
| 169 |
} |
183 |
} |
| 170 |
|
184 |
|
| 171 |
// TODO run asynchronously |
|
|
| 172 |
synchronized void updatePreview() { |
185 |
synchronized void updatePreview() { |
| 173 |
String regexp = regexpText.getText(); |
186 |
if(updatePreviewJob==null) { |
| 174 |
try { |
187 |
updatePreviewJob = new UpdatePreviewJob("Updating preview"); |
| 175 |
Pattern p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ); |
188 |
updatePreviewJob.setPriority(Job.DECORATE); |
| 176 |
Matcher matcher = p.matcher(getWebPage()); |
189 |
} |
| 177 |
|
190 |
updatePreviewJob.setParams(queryUrlText.getText(), regexpText.getText()); |
| 178 |
previewTable.removeAll(); |
191 |
if(!updatePreviewJob.isActive()) { |
| 179 |
|
192 |
updatePreviewJob.schedule(); |
| 180 |
while(matcher.find()) { |
193 |
} |
| 181 |
if(matcher.groupCount()>0) { |
194 |
|
| 182 |
TableItem item = new TableItem(previewTable, SWT.NONE); |
195 |
} |
| 183 |
for (int i = 0; i < matcher.groupCount(); i++) { |
196 |
|
| 184 |
item.setText(i, matcher.group(i+1)); |
197 |
void updatePreviewTable(List<AbstractQueryHit> hits, MultiStatus queryStatus) { |
|
|
198 |
if(previewTable.isDisposed()) { |
| 199 |
return; |
| 200 |
} |
| 201 |
|
| 202 |
previewTable.removeAll(); |
| 203 |
|
| 204 |
if(hits!=null) { |
| 205 |
for (AbstractQueryHit hit : hits) { |
| 206 |
TableItem item = new TableItem(previewTable, SWT.NONE); |
| 207 |
if(hit.getId()!=null) { |
| 208 |
item.setText(0, hit.getId()); |
| 209 |
if(hit.getDescription()!=null) { |
| 210 |
item.setText(1, hit.getDescription()); |
| 185 |
} |
211 |
} |
| 186 |
} |
212 |
} |
| 187 |
|
213 |
} |
| 188 |
if(matcher.groupCount()<2) { |
214 |
} |
| 189 |
setErrorMessage("Require two matching groups (id and description)"); |
215 |
|
| 190 |
setPageComplete(false); |
216 |
if(queryStatus.isOK()) { |
| 191 |
} else { |
217 |
setErrorMessage(null); |
| 192 |
setErrorMessage(null); |
218 |
setPageComplete(true); |
| 193 |
setPageComplete(true); |
219 |
} else { |
| 194 |
} |
220 |
StringBuffer sb = new StringBuffer(); |
| 195 |
} |
221 |
for (IStatus status : queryStatus.getChildren()) { |
| 196 |
|
222 |
sb.append(status.getMessage()).append("\n"); |
| 197 |
} catch(Exception ex) { |
223 |
} |
| 198 |
setErrorMessage("Parsing error: "+ex.getMessage()); |
224 |
setErrorMessage(sb.toString()); |
| 199 |
setPageComplete(false); |
225 |
setPageComplete(false); |
| 200 |
} |
226 |
} |
| 201 |
} |
227 |
} |
| 202 |
|
228 |
|
| 203 |
private StringBuffer getWebPage() { |
229 |
private final class UpdatePreviewJob extends Job { |
| 204 |
if(webPage==null) { |
230 |
private volatile String url; |
| 205 |
try { |
231 |
private volatile String regexp; |
| 206 |
webPage = WebRepositoryConnector.fetchResource(queryUrlText.getText()); |
232 |
private volatile boolean active = false; |
| 207 |
} catch(Exception ex) { |
233 |
|
| 208 |
setErrorMessage("Unable to fetch resource: "+ex.getMessage()); |
234 |
private UpdatePreviewJob(String name) { |
| 209 |
setPageComplete(false); |
235 |
super(name); |
| 210 |
} |
236 |
} |
|
|
237 |
|
| 238 |
public boolean isActive() { |
| 239 |
return active; |
| 240 |
} |
| 241 |
|
| 242 |
public void setParams(String url, String regexp) { |
| 243 |
this.url = url; |
| 244 |
this.regexp = regexp; |
| 245 |
} |
| 246 |
|
| 247 |
protected IStatus run(IProgressMonitor monitor) { |
| 248 |
String currentUrl = url; |
| 249 |
String currentRegexp = regexp; |
| 250 |
active = true; |
| 251 |
do { |
| 252 |
final MultiStatus queryStatus = new MultiStatus(MylarTaskListPlugin.PLUGIN_ID, IStatus.OK, "Query result", null); |
| 253 |
List<AbstractQueryHit> hits = null; |
| 254 |
try { |
| 255 |
if(webPage==null) { |
| 256 |
webPage = WebRepositoryConnector.fetchResource(currentUrl); |
| 257 |
} |
| 258 |
|
| 259 |
hits = WebRepositoryConnector.performQuery(webPage, currentRegexp, null, null, monitor, queryStatus); |
| 260 |
|
| 261 |
} catch (final IOException ex) { |
| 262 |
queryStatus.add(new Status(IStatus.ERROR, MylarTaskListPlugin.PLUGIN_ID, IStatus.ERROR, |
| 263 |
"Unable to fetch resource: "+ex.getMessage(), null)); |
| 264 |
} catch (final Exception ex) { |
| 265 |
queryStatus.add(new Status(IStatus.ERROR, MylarTaskListPlugin.PLUGIN_ID, IStatus.ERROR, |
| 266 |
"Parsing error: "+ex.getMessage(), null)); |
| 267 |
} |
| 268 |
|
| 269 |
final List<AbstractQueryHit> queryHits = hits; |
| 270 |
Display.getDefault().asyncExec(new Runnable() { |
| 271 |
public void run() { |
| 272 |
updatePreviewTable(queryHits, queryStatus); |
| 273 |
} |
| 274 |
}); |
| 275 |
} while(currentRegexp!=regexp && !monitor.isCanceled()); |
| 276 |
active = false; |
| 277 |
return Status.OK_STATUS; |
| 211 |
} |
278 |
} |
| 212 |
return webPage; |
|
|
| 213 |
} |
279 |
} |
| 214 |
|
280 |
|
| 215 |
|
281 |
|
| 216 |
// /** |
282 |
/** |
| 217 |
// * Simple proposal provider for regexps |
283 |
* Simple proposal provider for regexps |
| 218 |
// */ |
284 |
*/ |
| 219 |
// private static final class RegExpProposalProvider implements IContentProposalProvider { |
285 |
private static final class RegExpProposalProvider implements IContentProposalProvider { |
| 220 |
// private static final String[] LABELS = { |
286 |
private static final String[] LABELS = { |
| 221 |
// "IssueZilla", |
287 |
"IssueZilla", |
| 222 |
// "GForge", |
288 |
"GForge", |
| 223 |
// "Trac", |
289 |
"Trac", |
| 224 |
// "Jira", |
290 |
"Jira", |
| 225 |
// "vBulletin" |
291 |
"vBulletin" |
| 226 |
// }; |
292 |
}; |
| 227 |
// private static final String[] PROPOSALS = { |
293 |
private static final String[] PROPOSALS = { |
| 228 |
// "<a href=\"show_bug.cgi\\?id\\=(.+?)\">.+?<span class=\"summary\">(.+?)</span>", |
294 |
"<a href=\"show_bug.cgi\\?id\\=(.+?)\">.+?<span class=\"summary\">(.+?)</span>", |
| 229 |
// "<a class=\"tracker\" href=\"/tracker/index.php\\?func=detail&aid=(.+?)&group_id=GROUP&atid=ATID\">(.+?)</a></td>", |
295 |
"<a class=\"tracker\" href=\"/tracker/index.php\\?func=detail&aid=(.+?)&group_id=GROUP&atid=ATID\">(.+?)</a></td>", |
| 230 |
// "<td class=\"summary\"><a title=\"View ticket\" href=\"/project/ticket/(.+?)\">(.+?)</a></td>", |
296 |
"<td class=\"summary\"><a title=\"View ticket\" href=\"/project/ticket/(.+?)\">(.+?)</a></td>", |
| 231 |
// "<td class=\"nav summary\">\\s+?<a href=\"/browse/(.+?)\".+?>(.+?)</a>", |
297 |
"<td class=\"nav summary\">\\s+?<a href=\"/browse/(.+?)\".+?>(.+?)</a>", |
| 232 |
// "<a href=\"showthread.php\\?.+?t=(\\d+?)\" id=\"thread_title_\\1\">(.+?)</a>" |
298 |
"<a href=\"showthread.php\\?.+?t=(\\d+?)\" id=\"thread_title_\\1\">(.+?)</a>" |
| 233 |
// }; |
299 |
}; |
| 234 |
// |
300 |
|
| 235 |
// public IContentProposal[] getProposals(String contents, int position) { |
301 |
public IContentProposal[] getProposals(String contents, int position) { |
| 236 |
// IContentProposal[] res = new IContentProposal[LABELS.length]; |
302 |
IContentProposal[] res = new IContentProposal[LABELS.length]; |
| 237 |
// for (int i = 0; i < LABELS.length; i++) { |
303 |
for (int i = 0; i < LABELS.length; i++) { |
| 238 |
// final String label = LABELS[i]; |
304 |
final String label = LABELS[i]; |
| 239 |
// final String content = PROPOSALS[i]; |
305 |
final String content = PROPOSALS[i]; |
| 240 |
// res[i] = new IContentProposal() { |
306 |
res[i] = new IContentProposal() { |
| 241 |
// public String getContent() { |
307 |
public String getContent() { |
| 242 |
// return content; |
308 |
return content; |
| 243 |
// } |
309 |
} |
| 244 |
// public int getCursorPosition() { |
310 |
public int getCursorPosition() { |
| 245 |
// return content.length(); |
311 |
return content.length(); |
| 246 |
// } |
312 |
} |
| 247 |
// public String getDescription() { |
313 |
public String getDescription() { |
| 248 |
// return content; |
314 |
return content; |
| 249 |
// } |
315 |
} |
| 250 |
// public String getLabel() { |
316 |
public String getLabel() { |
| 251 |
// return label; |
317 |
return label; |
| 252 |
// } |
318 |
} |
| 253 |
// }; |
319 |
}; |
| 254 |
// } |
320 |
} |
| 255 |
// return res; |
321 |
return res; |
| 256 |
// } |
322 |
} |
| 257 |
// } |
323 |
} |
| 258 |
|
324 |
|
| 259 |
} |
325 |
} |
| 260 |
|
326 |
|