summaryrefslogtreecommitdiffstats
path: root/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java')
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java543
1 files changed, 543 insertions, 0 deletions
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java
new file mode 100644
index 0000000..61878b9
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java
@@ -0,0 +1,543 @@
1/*****************************************************************************
2 * Copyright (c) 2009 Ken Gilmer
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Ken Gilmer - initial API and implementation
10 * Jessica Zhang (Intel) - Extend to support auto-fill base on src_uri value
11 *******************************************************************************/
12package org.yocto.bc.ui.wizards;
13
14import org.eclipse.core.resources.IContainer;
15import org.eclipse.core.resources.IProject;
16import org.eclipse.core.resources.IResource;
17import org.eclipse.core.resources.ResourcesPlugin;
18import org.eclipse.core.runtime.Path;
19import org.eclipse.core.runtime.IPath;
20import org.eclipse.jface.viewers.ISelection;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.jface.window.Window;
23import org.eclipse.jface.wizard.WizardPage;
24import org.eclipse.swt.SWT;
25import org.eclipse.swt.events.ModifyEvent;
26import org.eclipse.swt.events.ModifyListener;
27import org.eclipse.swt.events.SelectionAdapter;
28import org.eclipse.swt.events.SelectionEvent;
29import org.eclipse.swt.layout.GridData;
30import org.eclipse.swt.layout.GridLayout;
31import org.eclipse.swt.widgets.Button;
32import org.eclipse.swt.widgets.Composite;
33import org.eclipse.swt.widgets.DirectoryDialog;
34import org.eclipse.swt.widgets.FileDialog;
35import org.eclipse.swt.widgets.Label;
36import org.eclipse.swt.widgets.Text;
37import org.eclipse.ui.dialogs.ContainerSelectionDialog;
38
39import java.util.HashMap;
40import java.util.Hashtable;
41import java.util.Set;
42import java.util.ArrayList;
43import java.util.Enumeration;
44import java.util.Iterator;
45
46import java.io.BufferedReader;
47import java.io.InputStreamReader;
48import java.io.File;
49import java.io.FileReader;
50import java.io.IOException;
51import java.io.FileInputStream;
52import java.io.InputStream;
53import java.io.FilenameFilter;
54import java.security.MessageDigest;
55import java.math.BigInteger;
56
57public class NewBitBakeFileRecipeWizardPage extends WizardPage {
58 private Text containerText;
59 private Text fileText;
60
61 private Text descriptionText;
62 private Text licenseText;
63 private Text checksumText;
64 private Text homepageText;
65 private Text authorText;
66 private Text sectionText;
67 private Text srcuriText;
68 private Text md5sumText;
69 private Text sha256sumText;
70 private BitbakeRecipeUIElement element;
71
72 private ISelection selection;
73 private String metaDirLoc;
74 private ArrayList inheritance;
75
76 public NewBitBakeFileRecipeWizardPage(ISelection selection) {
77 super("wizardPage");
78 setTitle("BitBake Recipe");
79 setDescription("Create a new BitBake recipe.");
80 this.selection = selection;
81 element = new BitbakeRecipeUIElement();
82 inheritance = new ArrayList();
83 }
84
85 public void createControl(Composite parent) {
86 final Composite container = new Composite(parent, SWT.NULL);
87 GridLayout layout = new GridLayout();
88 container.setLayout(layout);
89 layout.numColumns = 3;
90 layout.verticalSpacing = 9;
91
92 Label label = new Label(container, SWT.NULL);
93 GridData gd = new GridData();
94 gd.horizontalSpan = 3;
95 label.setLayoutData(gd);
96
97 label = new Label(container, SWT.NULL);
98 label.setText("Recipe &Directory:");
99
100 containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
101 gd = new GridData(GridData.FILL_HORIZONTAL);
102 containerText.setLayoutData(gd);
103 containerText.addModifyListener(new ModifyListener() {
104 public void modifyText(ModifyEvent e) {
105 dialogChanged();
106 }
107 });
108
109 Button buttonBrowse = new Button(container, SWT.PUSH);
110 buttonBrowse.setText("Browse...");
111 buttonBrowse.addSelectionListener(new SelectionAdapter() {
112 @Override
113 public void widgetSelected(SelectionEvent e) {
114 handleBrowse(container, containerText);
115 }
116 });
117
118 label = new Label(container, SWT.NULL);
119 gd = new GridData();
120 gd.horizontalSpan = 3;
121 label.setLayoutData(gd);
122
123 label = new Label(container, SWT.NULL);
124 label.setText("SRC_&URI:");
125
126 srcuriText = new Text(container, SWT.BORDER | SWT.SINGLE);
127 gd = new GridData(GridData.FILL_HORIZONTAL);
128 srcuriText.setLayoutData(gd);
129 srcuriText.addModifyListener(new ModifyListener() {
130 public void modifyText(ModifyEvent e) {
131 dialogChanged();
132 }
133 });
134
135 Button buttonP = new Button(container, SWT.PUSH);
136 buttonP.setText("Populate...");
137 buttonP.addSelectionListener(new SelectionAdapter() {
138 @Override
139 public void widgetSelected(SelectionEvent e) {
140 handlePopulate();
141 }
142 });
143
144 createField(container, "&Recipe Name:", (fileText = new Text(container, SWT.BORDER | SWT.SINGLE)));
145 createField(container, "SRC_URI[&md5sum]:", (md5sumText = new Text(container, SWT.BORDER | SWT.SINGLE)));
146 createField(container, "SRC_URI[&sha256sum]:", (sha256sumText = new Text(container, SWT.BORDER | SWT.SINGLE)));
147 createField(container, "License File &Checksum:", (checksumText = new Text(container, SWT.BORDER | SWT.SINGLE)));
148 createField(container, "&Package Description:", (descriptionText = new Text(container, SWT.BORDER | SWT.SINGLE)));
149 createField(container, "&License:", (licenseText = new Text(container, SWT.BORDER | SWT.SINGLE)));
150
151 createField(container, "&Homepage:", (homepageText = new Text(container, SWT.BORDER | SWT.SINGLE)));
152 createField(container, "Package &Author:", (authorText = new Text(container, SWT.BORDER | SWT.SINGLE)));
153 createField(container, "&Section:", (sectionText = new Text(container, SWT.BORDER | SWT.SINGLE)));
154
155 initialize();
156 dialogChanged();
157 setControl(container);
158 }
159
160 private void createField(Composite container, String title, Text control) {
161 Label label = new Label(container, SWT.NONE);
162 label.setText(title);
163 label.moveAbove(control);
164
165 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
166 gd.horizontalSpan = 2;
167 control.setLayoutData(gd);
168 control.addModifyListener(new ModifyListener() {
169
170 public void modifyText(ModifyEvent e) {
171 dialogChanged();
172 }
173
174 });
175 }
176
177 private void dialogChanged() {
178 String containerName = containerText.getText();
179 IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(containerName));
180 String fileName = fileText.getText();
181
182 if (containerName.length() == 0) {
183 updateStatus("Directory must be specified");
184 return;
185 }
186
187 if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
188 updateStatus("File container must exist");
189 return;
190 }
191 if (!container.isAccessible()) {
192 updateStatus("Project must be writable");
193 return;
194 }
195
196 IProject project = container.getProject();
197 metaDirLoc = project.getLocation().toString() + "/meta";
198
199 if (fileName.length() == 0) {
200 updateStatus("File name must be specified");
201 return;
202 }
203 if (fileName.contains(" ")) {
204 updateStatus("File name must be valid with no space in it");
205 return;
206 }
207 if (fileName.replace('\\', '/').indexOf('/', 1) > 0) {
208 updateStatus("File name must be valid");
209 return;
210 }
211
212 if (descriptionText.getText().length() == 0) {
213 updateStatus("Recipe must have a description");
214 return;
215 }
216
217 if (licenseText.getText().length() == 0) {
218 updateStatus("Recipe must have a license");
219 return;
220 }
221
222 if (srcuriText.getText().length() == 0) {
223 updateStatus("SRC_URI can't be empty");
224 }
225
226 updateStatus(null);
227 }
228
229 public BitbakeRecipeUIElement getUIElement() {
230 element.setAuthor(authorText.getText());
231 element.setChecksum(checksumText.getText());
232 element.setContainer(containerText.getText());
233 element.setDescription(descriptionText.getText());
234 element.setFile(fileText.getText());
235 element.setHomePage(homepageText.getText());
236 element.setLicense(licenseText.getText());
237 element.setMd5sum(md5sumText.getText());
238 element.setSection(sectionText.getText());
239 element.setSha256sum(sha256sumText.getText());
240 element.setSrcuri(srcuriText.getText());
241 element.setInheritance(inheritance);
242 element.setMetaDir(metaDirLoc);
243
244 return element;
245 }
246
247 private void handleBrowse(final Composite parent, final Text text) {
248 ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, "Select project directory");
249 if (dialog.open() == Window.OK) {
250 Object[] result = dialog.getResult();
251 if (result.length == 1) {
252 text.setText(((Path) result[0]).toString());
253 }
254 }
255 }
256
257 private void handlePopulate() {
258 String src_uri = srcuriText.getText();
259 if ((src_uri.startsWith("http://") || src_uri.startsWith("ftp://"))
260 && (src_uri.endsWith("tar.gz") || src_uri.endsWith("tar.bz2"))) {
261
262 HashMap<String, String> mirror_map = createMirrorLookupTable();
263
264 populateRecipeName(src_uri);
265 populateSrcuriChecksum(src_uri);
266 String extractDir = extractPackage(src_uri);
267 populateLicensefileChecksum(extractDir);
268 updateSrcuri(mirror_map, src_uri);
269 populateInheritance(extractDir);
270 } else if (src_uri.startsWith("file://")) {
271 String path_str = src_uri.substring(7);
272 File package_dir = new File(path_str);
273 if (package_dir.isDirectory()) {
274 String package_name = path_str.substring(path_str.lastIndexOf("/")+1);
275 fileText.setText(package_name+".bb");
276 populateLicensefileChecksum(path_str);
277 populateInheritance(path_str);
278 }
279 }
280
281 }
282
283 private String extractPackage(String src_uri) {
284 try {
285 File working_dir = new File(metaDirLoc+"/temp");
286 int idx = src_uri.lastIndexOf("/");
287 String tar_file = src_uri.substring(idx+1);
288 int tar_file_surfix_idx = tar_file.lastIndexOf(".tar");
289 String tar_file_surfix = tar_file.substring(tar_file_surfix_idx);
290 String tar_file_path = metaDirLoc+"/temp/"+tar_file;
291
292 String tar_cmd = "";
293 int tar_idx = 0;
294 if (tar_file_surfix.matches(".tar.gz")) {
295 tar_cmd = "tar -zxvf "+ tar_file_path;
296 tar_idx = tar_file_path.lastIndexOf(".tar.gz");
297 } else if (tar_file_surfix.matches(".tar.bz2")) {
298 tar_idx = tar_file_path.lastIndexOf(".tar.bz2");
299 tar_cmd = "tar -xvf " + tar_file_path;
300 }
301 final Process process = Runtime.getRuntime().exec(tar_cmd, null, working_dir);
302 int returnCode = process.waitFor();
303 if (returnCode == 0) {
304 return tar_file_path.substring(0, tar_idx);
305 }
306 } catch (Exception e) {
307 e.printStackTrace();
308 }
309 return null;
310 }
311
312 private void populateInheritance(String extractDir) {
313 File extract_dir = new File(extractDir);
314
315 File[] files = extract_dir.listFiles();
316 for (File file : files) {
317 if (file.isDirectory())
318 continue;
319 else {
320 if (file.getName().equalsIgnoreCase("cmakelists.txt"))
321 inheritance.add("cmake");
322 else if (file.getName().equalsIgnoreCase("setup.py"))
323 inheritance.add("disutils");
324 else {
325 String pattern = "configure.[ac|.in]";
326 if (file.getName().equalsIgnoreCase("configure.ac") || file.getName().equalsIgnoreCase("configure.in"))
327 inheritance.add("autotools");
328 else
329 continue;
330 }
331 }
332 }
333 }
334
335 private void populateLicensefileChecksum(String extractDir) {
336 String licenseFileChecksum_str = null;
337 String licenseFilePath = null;
338
339 try {
340 File extract_dir = new File(extractDir);
341
342 FilenameFilter copyFilter = new FilenameFilter() {
343 public boolean accept(File dir, String name) {
344 if (name.startsWith("COPYING")) {
345 return true;
346 } else {
347 return false;
348 }
349 }
350 };
351
352 File copyFile = null;
353 File[] files = extract_dir.listFiles(copyFilter);
354 for (File file : files) {
355 if (file.isDirectory())
356 continue;
357 else {
358 copyFile = file;
359 licenseFilePath = file.getCanonicalPath();
360 break;
361 }
362 }
363
364 MessageDigest digest_md5 = MessageDigest.getInstance("MD5");
365 InputStream is = new FileInputStream(copyFile);
366 byte[] buffer = new byte[8192];
367 int read = 0;
368
369 while( (read = is.read(buffer)) > 0) {
370 digest_md5.update(buffer, 0, read);
371 }
372 byte[] md5sum = digest_md5.digest();
373 BigInteger bigInt_md5 = new BigInteger(1, md5sum);
374 licenseFileChecksum_str = bigInt_md5.toString(16);
375 is.close();
376 } catch (Exception e) {
377 throw new RuntimeException("Unable to process file for MD5 calculation", e);
378 }
379
380 if (licenseFileChecksum_str != null) {
381 int idx = licenseFilePath.lastIndexOf("/");
382 String license_file_name = licenseFilePath.substring(idx+1);
383 checksumText.setText("file://"+license_file_name+";md5="+licenseFileChecksum_str);
384 }
385 }
386
387 private void populateSrcuriChecksum(String src_uri) {
388 String md5sum_str = null;
389 String sha256sum_str = null;
390
391 try {
392 File working_dir = new File(metaDirLoc+"/temp");
393 working_dir.mkdir();
394 String download_cmd = "wget " + src_uri;
395 final Process process = Runtime.getRuntime().exec(download_cmd, null, working_dir);
396 int returnCode = process.waitFor();
397 if (returnCode == 0) {
398 int idx = src_uri.lastIndexOf("/");
399 String tar_file = src_uri.substring(idx+1);
400 String tar_file_path = metaDirLoc+"/temp/"+tar_file;
401 MessageDigest digest_md5 = MessageDigest.getInstance("MD5");
402 MessageDigest digest_sha256 = MessageDigest.getInstance("SHA-256");
403 File f = new File(tar_file_path);
404 InputStream is = new FileInputStream(f);
405 byte[] buffer = new byte[8192];
406 int read = 0;
407 try {
408 while( (read = is.read(buffer)) > 0) {
409 digest_md5.update(buffer, 0, read);
410 digest_sha256.update(buffer, 0, read);
411 }
412 byte[] md5sum = digest_md5.digest();
413 byte[] sha256sum = digest_sha256.digest();
414 BigInteger bigInt_md5 = new BigInteger(1, md5sum);
415 BigInteger bigInt_sha256 = new BigInteger(1, sha256sum);
416 md5sum_str = bigInt_md5.toString(16);
417 sha256sum_str = bigInt_sha256.toString(16);
418 }
419 catch(IOException e) {
420 throw new RuntimeException("Unable to process file for MD5", e);
421 }
422 finally {
423 try {
424 is.close();
425 }
426 catch(IOException e) {
427 throw new RuntimeException("Unable to close input stream for MD5 calculation", e);
428 }
429 }
430 if (md5sum_str != null)
431 md5sumText.setText(md5sum_str);
432 if (sha256sum_str != null)
433 sha256sumText.setText(sha256sum_str);
434 }
435 } catch (Exception e) {
436 e.printStackTrace();
437 }
438 }
439
440 private HashMap<String, String> createMirrorLookupTable() {
441 HashMap<String, String> mirror_map = new HashMap<String, String>();
442 File mirror_file = new File(metaDirLoc+"/classes/mirrors.bbclass");
443
444 try {
445 if (mirror_file.exists()) {
446 BufferedReader input = new BufferedReader(new FileReader(mirror_file));
447
448 try
449 {
450 String line = null;
451 String delims = "[\\t]+";
452
453 while ((line = input.readLine()) != null)
454 {
455 String[] tokens = line.split(delims);
456 if (tokens.length < 2)
457 continue;
458 String ending_str = " \\n \\";
459 int idx = tokens[1].lastIndexOf(ending_str);
460 String key = tokens[1].substring(0, idx);
461 mirror_map.put(key, tokens[0]);
462 }
463 }
464 finally {
465 input.close();
466 }
467 }
468 }
469 catch (IOException e)
470 {
471 e.printStackTrace();
472
473 }
474 return mirror_map;
475 }
476
477 private void populateRecipeName(String src_uri) {
478 String file_name = fileText.getText();
479 if (!file_name.isEmpty())
480 return;
481 String delims = "[/]+";
482 String recipe_file = null;
483
484 String[] tokens = src_uri.split(delims);
485 if (tokens.length > 0) {
486 String tar_file = tokens[tokens.length - 1];
487 int surfix_idx = 0;
488 if (tar_file.endsWith(".tar.gz"))
489 surfix_idx = tar_file.lastIndexOf(".tar.gz");
490 else
491 surfix_idx = tar_file.lastIndexOf(".tar.bz2");
492 int sept_idx = tar_file.lastIndexOf("-");
493 recipe_file = tar_file.substring(0, sept_idx)+"_"+tar_file.substring(sept_idx+1, surfix_idx)+".bb";
494 }
495 if (recipe_file != null)
496 fileText.setText(recipe_file);
497 }
498
499 private void updateSrcuri(HashMap<String, String> mirrorsMap, String src_uri) {
500 Set<String> mirrors = mirrorsMap.keySet();
501 Iterator iter = mirrors.iterator();
502 String mirror_key = null;
503
504 while (iter.hasNext()) {
505 String value = (String)iter.next();
506 if (src_uri.startsWith(value)) {
507 mirror_key = value;
508 break;
509 }
510 }
511
512 if (mirror_key != null) {
513 String replace_string = (String)mirrorsMap.get(mirror_key);
514 if (replace_string != null)
515 src_uri = replace_string+src_uri.substring(mirror_key.length());
516 }
517 int idx = src_uri.lastIndexOf("-");
518 String new_src_uri = src_uri.substring(0, idx)+"-${PV}.tar.gz";
519 srcuriText.setText(new_src_uri);
520 }
521
522 private void initialize() {
523 if (selection != null && selection.isEmpty() == false && selection instanceof IStructuredSelection) {
524 IStructuredSelection ssel = (IStructuredSelection) selection;
525 if (ssel.size() > 1)
526 return;
527 Object obj = ssel.getFirstElement();
528 if (obj instanceof IResource) {
529 IContainer container;
530 if (obj instanceof IContainer)
531 container = (IContainer) obj;
532 else
533 container = ((IResource) obj).getParent();
534 containerText.setText(container.getFullPath().toString());
535 }
536 }
537 }
538
539 private void updateStatus(String message) {
540 setErrorMessage(message);
541 setPageComplete(message == null);
542 }
543} \ No newline at end of file