summaryrefslogtreecommitdiffstats
path: root/plugins/org.yocto.bc.ui/src
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.yocto.bc.ui/src')
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBCommonVars.java24
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBLanguageHelper.java62
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBRecipe.java50
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBSession.java739
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/IBBSessionListener.java18
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ICommandResponseHandler.java15
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ProjectInfoHelper.java105
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java248
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/Activator.java266
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/BCResourceChangeListener.java64
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/AbstractBitbakeCommandAction.java199
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeBuildRecipeAction.java24
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeCleanRecipeAction.java26
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeImportAction.java106
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeRebuildRecipeAction.java29
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobAction.java84
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobDialog.java328
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobHandler.java50
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewBitBakeProjectWizardAction.java48
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewRecipeWizardAction.java48
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchVariableWizardAction.java78
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeBuilder.java177
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeCommanderNature.java118
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/ToggleNatureAction.java106
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ProjectDecorator.java48
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ReadOnly.java107
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BBVariableTextHover.java118
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeDocumentProvider.java62
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeFileEditor.java75
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java195
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/CustomFunctionRule.java94
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeCompletionProcessor.java127
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorActionContributor.java47
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.java21
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.properties14
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/VariableRule.java69
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Messages.java48
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFile.java515
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystem.java78
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystemContributor.java30
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEIgnoreFile.java133
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Policy.java108
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/IModelElement.java15
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/ProjectInfo.java48
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/perspectives/BitbakeCommanderPerspective.java89
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/popup/actions/NewAction.java43
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeContentProvider.java60
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeView.java165
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/BitbakeRecipeUIElement.java145
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizard.java56
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizardPage.java149
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizard.java215
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizardPage.java543
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/BBCProjectPage.java236
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/ImportYoctoProjectWizard.java166
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/InstallWizard.java404
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/OptionsPage.java247
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/BBConfigurationInitializeOperation.java50
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/CreateBBCProjectOperation.java102
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariablePage.java262
-rw-r--r--plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariableWizard.java43
61 files changed, 7939 insertions, 0 deletions
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBCommonVars.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBCommonVars.java
new file mode 100644
index 0000000..d905e50
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBCommonVars.java
@@ -0,0 +1,24 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13/**
14 * Constants for commonly used bitbake variables.
15 * @author kgilmer
16 *
17 */
18public class BBCommonVars {
19 public final static String WORKDIR = "WORKDIR";
20 public static final String PN = "PN";
21 public static final String S = "S";
22 public static final String PV = "PV";
23
24}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBLanguageHelper.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBLanguageHelper.java
new file mode 100644
index 0000000..8ebe134
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBLanguageHelper.java
@@ -0,0 +1,62 @@
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 * Lianhao Lu (Intel) - add more bitbake keywords and functions
11 *******************************************************************************/
12package org.yocto.bc.bitbake;
13
14import java.util.Comparator;
15import java.util.Map;
16import java.util.TreeMap;
17
18/**
19 * Here is where all BitBake-related information is centralized.
20 * @author kgilmer
21 *
22 */
23public class BBLanguageHelper {
24
25 public static final String[] BITBAKE_KEYWORDS = new String[] { "inherit", "require", "export", "addtask", "python", "include", "fakeroot", "addhandler", "def"};
26 public static final String[] SHELL_KEYWORDS = new String[] { "while", "do", "if", "fi", "ln", "export", "install", "oe_libinstall", "for", "in", "done", "echo", "then", "cat", "rm", "rmdir", "mkdir", "printf", "exit", "test", "cd", "cp"};
27 public static final String[] BITBAKE_STANDARD_FUNCTIONS = new String[] { "fetch", "unpack", "patch", "configure", "compile", "install", "populate_sysroot", "package"};
28 public static final String BITBAKE_RECIPE_FILE_EXTENSION = "bb";
29
30 /**
31 * @return A map of names and descriptions of commonly used BitBake variables.
32 */
33 public static Map<String, String> getCommonBitbakeVariables() {
34 Map<String, String> m = new TreeMap<String, String>(new Comparator<Object>() {
35
36 public int compare(Object o1, Object o2) {
37
38 return ((String) o1).compareTo(((String) o2));
39 }
40
41 });
42
43 m.put("SECTION", "Category of package");
44 m.put("PR", "Package Release Number");
45 m.put("SRC_URI", "Location of package sources");
46 m.put("DESCRIPTION", "Description of package");
47 m.put("EXTRA_OEMAKE", "Extra flags to pass to the package makefile");
48 m.put("EXTRA_OECONF", "Extra configuration flags for the package makefile");
49 m.put("DEPENDS", "The set of build-time dependent packages");
50 m.put("RDEPENDS", "The set of run-time dependent packages");
51 m.put("HOMEPAGE", "Homepage of the package");
52 m.put("LICENSE", "License of the package");
53 m.put("FILES_${PN}", "Full file path of files on target.");
54 m.put("S", "Package source directory");
55 m.put("PV", "Package version");
56 m.put("AUTHOR", "Author or maintainer of package");
57 m.put("PRIORITY", "Priority of package");
58
59 return m;
60 }
61
62}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBRecipe.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBRecipe.java
new file mode 100644
index 0000000..2b355ba
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBRecipe.java
@@ -0,0 +1,50 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13import java.io.IOException;
14
15import org.eclipse.jface.preference.JFacePreferences;
16import org.eclipse.jface.resource.JFaceResources;
17import org.eclipse.swt.widgets.Display;
18import org.eclipse.ui.console.ConsolePlugin;
19import org.eclipse.ui.console.IConsole;
20import org.eclipse.ui.console.MessageConsole;
21import org.eclipse.ui.console.MessageConsoleStream;
22
23/**
24 * Represents the bitbake environment of a recipe package.
25 * @author kgilmer
26 *
27 */
28public class BBRecipe extends BBSession {
29 private final BBSession session;
30 private final String filePath;
31
32 public BBRecipe(BBSession session, String filePath) throws IOException {
33 super(session.shell, session.pinfo.getRootPath());
34 this.session = session;
35 this.filePath = filePath;
36 this.parsingCmd = "DISABLE_SANITY_CHECKS=1 bitbake -e -b " + filePath;
37 }
38
39 @Override
40 public void initialize() throws Exception {
41 if (this.size() == 0) {
42 //System.out.println("Failed to parse " + filePath);
43 //throw new IOException("Failed to parse " + filePath);
44 }
45 }
46
47 protected String getDefaultDepends() {
48 return this.filePath;
49 }
50}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBSession.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBSession.java
new file mode 100644
index 0000000..e998bcd
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/BBSession.java
@@ -0,0 +1,739 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13import java.io.BufferedReader;
14import java.io.File;
15import java.io.FileFilter;
16import java.io.IOException;
17import java.io.StringReader;
18import java.util.ArrayList;
19import java.util.Arrays;
20import java.util.Collection;
21import java.util.Hashtable;
22import java.util.Iterator;
23import java.util.List;
24import java.util.Map;
25import java.util.Set;
26import java.util.Stack;
27import java.util.concurrent.locks.ReentrantReadWriteLock;
28import java.util.concurrent.locks.Lock;
29
30import org.eclipse.core.resources.IFile;
31import org.eclipse.core.resources.IProject;
32import org.eclipse.core.resources.IResource;
33import org.eclipse.core.runtime.IProgressMonitor;
34import org.eclipse.core.runtime.IStatus;
35import org.eclipse.core.runtime.Status;
36import org.eclipse.jface.preference.JFacePreferences;
37import org.eclipse.jface.resource.JFaceResources;
38import org.eclipse.ui.console.ConsolePlugin;
39import org.eclipse.ui.console.IConsole;
40import org.eclipse.ui.console.IConsoleManager;
41import org.eclipse.ui.console.MessageConsole;
42import org.eclipse.ui.console.MessageConsoleStream;
43import org.eclipse.ui.progress.WorkbenchJob;
44
45import org.yocto.bc.ui.model.IModelElement;
46import org.yocto.bc.ui.model.ProjectInfo;
47
48/**
49 * BBSession encapsulates a global bitbake configuration and is the primary interface
50 * for actions against a BitBake installation.
51 *
52 * @author kgilmer
53 *
54 */
55public class BBSession implements IBBSessionListener, IModelElement, Map {
56 public static final int TYPE_VARIABLE_ASSIGNMENT = 1;
57 public static final int TYPE_UNKNOWN = 2;
58 public static final int TYPE_STATEMENT = 3;
59 public static final int TYPE_FLAG = 4;
60
61 public static final String BUILDDIR_INDICATORS [] = {
62 File.separatorChar + "conf" + File.separatorChar + "local.conf",
63 File.separatorChar + "conf" + File.separatorChar + "bblayers.conf",
64 };
65
66 protected final ProjectInfo pinfo;
67 protected final ShellSession shell;
68 protected Map properties = null;
69 protected List <String> depends = null;
70 protected boolean initialized = false;
71 protected MessageConsole sessionConsole;
72 private final ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
73 private final Lock rlock = rwlock.readLock();
74 private final Lock wlock = rwlock.writeLock();
75 protected String parsingCmd;
76 private boolean silent = false;
77
78 public BBSession(ShellSession ssession, String projectRoot) throws IOException {
79 shell = ssession;
80 this.pinfo = new ProjectInfo();
81 pinfo.setLocation(projectRoot);
82 pinfo.setInitScriptPath(ProjectInfoHelper.getInitScriptPath(projectRoot));
83 this.parsingCmd = "DISABLE_SANITY_CHECKS=1 bitbake -e";
84 }
85
86 public BBSession(ShellSession ssession, String projectRoot, boolean silent) throws IOException {
87 this(ssession, projectRoot);
88 this.silent = silent;
89 }
90
91 private Collection adapttoIPath(List<File> asList, IProject project) {
92
93 List pathList = new ArrayList();
94
95 for (Iterator i = asList.iterator(); i.hasNext();) {
96 File f = (File) i.next();
97 IFile ff = project.getFile(stripLeading(f.toString(), project.getLocationURI().getPath()));
98 if (ff.exists()) {
99 pathList.add(ff);
100 }
101 }
102
103 return pathList;
104 }
105
106 private String appendAll(String[] elems, int st) {
107 StringBuffer sb = new StringBuffer();
108
109 for (int i = st; i < elems.length; ++i) {
110 sb.append(elems[i]);
111 }
112
113 return sb.toString();
114 }
115
116 private int charCount(String trimmed, char c) {
117 int i = 0;
118 int p = 0;
119
120 while ((p = trimmed.indexOf(c, p)) > -1) {
121 i++;
122 p++;
123 }
124
125 return i;
126 }
127
128 public void clear() {
129 throw new RuntimeException("BB configuration is read-only.");
130 }
131
132 public boolean containsKey(Object arg0) {
133 try {
134 checkValidAndLock(true);
135 return properties.containsKey(arg0);
136 } catch (Exception e) {
137 e.printStackTrace();
138 return false;
139 }finally {
140 rlock.unlock();
141 }
142 }
143
144 public boolean containsValue(Object arg0) {
145 try {
146 checkValidAndLock(true);
147 return properties.containsValue(arg0);
148 } catch (Exception e) {
149 e.printStackTrace();
150 return false;
151 }finally {
152 rlock.unlock();
153 }
154 }
155
156 public Set entrySet() {
157 try {
158 checkValidAndLock(true);
159 return properties.entrySet();
160 } catch (Exception e) {
161 e.printStackTrace();
162 return null;
163 }finally {
164 rlock.unlock();
165 }
166 }
167
168 @Override
169 public boolean equals(Object arg0) {
170 try {
171 checkValidAndLock(true);
172 return properties.equals(arg0);
173 } catch (Exception e) {
174 e.printStackTrace();
175 return false;
176 }finally {
177 rlock.unlock();
178 }
179 }
180
181 public ShellSession getShell() {
182 return shell;
183 }
184
185 public String getProjInfoRoot() {
186 return pinfo.getRootPath();
187 }
188
189 /**
190 * Recursively generate list of Recipe files from a root directory.
191 *
192 * @param rootDir
193 * @param recipes
194 * @param fileExtension
195 * @param project
196 */
197 private void findRecipes(File rootDir, List recipes, final String fileExtension, IProject project) {
198 File[] children = rootDir.listFiles(new FileFilter() {
199
200 public boolean accept(File pathname) {
201 return pathname.isFile() && pathname.getName().endsWith(fileExtension);
202 }
203
204 });
205
206 if (children != null && children.length > 0) {
207 recipes.addAll(adapttoIPath(Arrays.asList(children), project));
208 }
209
210 File[] childDirs = rootDir.listFiles(new FileFilter() {
211
212 public boolean accept(File pathname) {
213 return pathname.isDirectory();
214 }
215
216 });
217
218 if (childDirs != null && childDirs.length > 0) {
219 for (int i = 0; i < childDirs.length; ++i) {
220 findRecipes(childDirs[i], recipes, fileExtension, project);
221 }
222 }
223 }
224
225 private Collection findRecipes(List paths, IProject project) {
226 List recipes = new ArrayList();
227
228 for (Iterator i = paths.iterator(); i.hasNext();) {
229 String rawPath = (String) i.next();
230 String[] elems = rawPath.split("\\*/\\*");
231
232 if (elems.length == 2) {
233
234 File rootDir = new File(elems[0]);
235
236 findRecipes(rootDir, recipes, elems[1], project);
237 }
238 }
239
240 return recipes;
241 }
242
243 public Object get(Object arg0) {
244 try {
245 checkValidAndLock(true);
246 return properties.get(arg0);
247 } catch (Exception e) {
248 e.printStackTrace();
249 return null;
250 }finally {
251 rlock.unlock();
252 }
253 }
254
255 private List getBitBakeKeywords() {
256 return Arrays.asList(BBLanguageHelper.BITBAKE_KEYWORDS);
257 }
258
259 /**
260 * @return A MessageConsole for this BB session.
261 */
262 public MessageConsole getConsole() {
263 if (sessionConsole == null) {
264 String cName = ProjectInfoHelper.getProjectName(pinfo.getRootPath()) + " Console";
265 IConsoleManager conMan = ConsolePlugin.getDefault().getConsoleManager();
266 IConsole[] existing = conMan.getConsoles();
267 for (int i = 0; i < existing.length; i++)
268 if (cName.equals(existing[i].getName())) {
269 sessionConsole = (MessageConsole) existing[i];
270 break;
271 }
272 if (sessionConsole == null) {
273 sessionConsole = new MessageConsole(cName, null);
274 conMan.addConsoles(new IConsole[] { sessionConsole });
275 }
276 }
277
278 ConsolePlugin.getDefault().getConsoleManager().showConsoleView(sessionConsole);
279
280 return sessionConsole;
281 }
282
283 private int getLineType(String line) {
284
285 if (line.contains("=")) {
286 return TYPE_VARIABLE_ASSIGNMENT;
287 }
288
289 for (Iterator i = getBitBakeKeywords().iterator(); i.hasNext();) {
290 if (line.startsWith((String) i.next())) {
291 return TYPE_STATEMENT;
292 }
293 }
294
295 if (line.contains(":")) {
296 return TYPE_FLAG;
297 }
298
299 return TYPE_UNKNOWN;
300 }
301
302 public Collection getRecipeFiles(IProject project) {
303 try {
304 checkValidAndLock(true);
305 if (!initialized) {
306 throw new RuntimeException(this.getClass().getName() + " is not initialized.");
307 }
308 String bbfiles = (String) this.properties.get("BBFILES");
309 List paths = parseBBFiles(bbfiles);
310 return findRecipes(paths, project);
311 } catch (Exception e) {
312 return null;
313 }
314 finally {
315 rlock.unlock();
316 }
317 }
318
319 @Override
320 public int hashCode() {
321 try {
322 checkValidAndLock(true);
323 return properties.hashCode();
324 } catch (Exception e) {
325 e.printStackTrace();
326 return 0;
327 }finally {
328 rlock.unlock();
329 }
330 }
331
332 protected int checkExecuteError(String result, int code) {
333 String recipe = getDefaultDepends();
334 String text = "Parsing " + ((recipe != null) ? ("recipe " + recipe) : "base configurations");
335 if (code != 0) {
336 text = text + " ERROR!\n" + result;
337 }else {
338 text = text + " SUCCESS.\n";
339 }
340 if(!silent) {
341 displayInConsole(text, code, false);
342 }
343 return code;
344 }
345
346 protected void displayInConsole(final String result, final int code, boolean clear) {
347 MessageConsole console = getConsole();
348 final MessageConsoleStream info = console.newMessageStream();
349 if(clear)
350 console.clearConsole();
351 new WorkbenchJob("Display parsing result") {
352 public IStatus runInUIThread(IProgressMonitor monitor) {
353 if(code != 0) {
354 info.setColor(JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR));
355 }
356 try {
357 info.println(result);
358 info.close();
359 }catch (Exception e) {
360 e.printStackTrace();
361 }
362 return Status.OK_STATUS;
363 }
364 }.schedule();
365 }
366
367 private void checkValidAndLock(boolean rdlck) throws Exception {
368 if(rdlck)
369 rlock.lock();
370 else
371 wlock.lock();
372 if(!initialized) {
373 //upgrade lock manually
374 if(rdlck) {
375 rlock.unlock();
376 wlock.lock();
377 }
378 try {
379 if(!initialized) { //recheck
380 int [] codes = {-1};
381 String result = shell.execute(parsingCmd, codes);
382 if(checkExecuteError(result, codes[0]) == 0) {
383 properties = parseBBEnvironment(result);
384 } else {
385 properties = parseBBEnvironment("");
386 }
387 initialized = true;
388 }
389 } finally {
390 //downgrade lock
391 if(rdlck) {
392 rlock.lock();
393 wlock.unlock();
394 }
395 }
396 }
397 //not release lock
398 }
399
400 public void initialize() throws Exception {
401 try {
402 checkValidAndLock(false);
403 }finally {
404 wlock.unlock();
405 }
406 }
407
408 private boolean isBlockEnd(String trimmed) {
409 return charCount(trimmed, '}') > charCount(trimmed, '{');
410 // return trimmed.indexOf('}') > -1 && trimmed.indexOf('{') == -1;
411 }
412
413 private boolean isBlockStart(String trimmed) {
414 return charCount(trimmed, '{') > charCount(trimmed, '}');
415 // return trimmed.indexOf('{') > -1 && trimmed.indexOf('}') == -1;
416 }
417
418 public boolean isEmpty() {
419 try {
420 checkValidAndLock(true);
421 return properties.isEmpty();
422 } catch (Exception e) {
423 e.printStackTrace();
424 return true;
425 }finally {
426 rlock.unlock();
427 }
428 }
429
430 public Set keySet() {
431 try {
432 checkValidAndLock(true);
433 return properties.keySet();
434 } catch (Exception e) {
435 e.printStackTrace();
436 return null;
437 }finally {
438 rlock.unlock();
439 }
440 }
441
442 protected void parse(String content, Map outMap) throws Exception {
443 BufferedReader reader = new BufferedReader(new StringReader(content));
444 String line;
445 boolean inLine = false;
446 StringBuffer sb = null;
447 Stack blockStack = new Stack();
448
449 while ((line = reader.readLine()) != null) {
450 String trimmed = line.trim();
451 if (trimmed.length() == 0 || line.startsWith("#")) {
452 // weed out the blank and comment lines
453 continue;
454 }
455 // Now we look for block start ends, and ignore all code within
456 // blocks.
457 if (isBlockStart(trimmed)) {
458 blockStack.push(trimmed);
459 } else if (isBlockEnd(trimmed)) {
460 blockStack.pop();
461
462 }
463
464 if (!blockStack.isEmpty()) {
465 // we are in a code block, continue until we break into global
466 // scope.
467 continue;
468 }
469 if (trimmed.endsWith("\\")) {
470 if (!inLine) {
471 inLine = true;
472 sb = new StringBuffer(trimmed.substring(0, trimmed.length() - 1));
473 } else {
474 sb.append(trimmed.substring(0, trimmed.length() - 1));
475 }
476 // Only parse the line when we have the complete contents.
477 continue;
478 } else if (inLine) {
479 inLine = false;
480 line = sb.toString();
481 }
482
483 parseLine(line, outMap);
484 }
485 }
486
487 private void parseAdditiveAssignment(String line, String operator, Map mo) throws Exception {
488 String[] elems = splitAssignment(line, "\\+=");
489
490 if (elems.length != 2) {
491 throw new Exception("Unable to parse additive variable assignment in line: " + line);
492 }
493
494 if (!mo.containsKey(elems[0])) {
495 mo.put(elems[0].trim(), elems[1]);
496 } else {
497 String existing = (String) mo.get(elems[0]);
498 if (operator.equals("+=")) {
499 mo.put(elems[0], existing + elems[1]);
500 } else {
501 mo.put(elems[0], elems[1] + existing);
502 }
503 }
504 }
505
506 protected String getDefaultDepends() {
507 return null;
508 }
509
510 protected Map parseBBEnvironment(String bbOut) throws Exception {
511 Map env = new Hashtable();
512 this.depends = new ArrayList<String>();
513
514 parse(bbOut, env);
515
516 String included = (String) env.get("BBINCLUDED");
517 if(getDefaultDepends() != null) {
518 this.depends.add(getDefaultDepends());
519 }
520 if(included != null) {
521 this.depends.addAll(Arrays.asList(included.split(" ")));
522 }
523
524 return env;
525 }
526
527
528 private List parseBBFiles(String bbfiles) {
529 return Arrays.asList(bbfiles.split(" "));
530 }
531
532 //Map delegate methods
533
534 private void parseConditionalAssignment(String line, Map mo) throws Exception {
535 String[] elems = splitAssignment(line, "\\?=");
536
537 if (elems.length != 2) {
538 throw new Exception("Unable to parse conditional variable assignment in line: " + line);
539 }
540
541 if (!mo.containsKey(elems[0].trim())) {
542 mo.put(elems[0].trim(), elems[1].trim());
543 }
544 }
545
546 private void parseImmediateAssignment(String line, String delimiter, Map mo) throws Exception {
547 String[] elems = splitAssignment(line, delimiter);
548
549 mo.put(elems[0], substitute(elems[1], mo));
550 }
551
552 private void parseKeyValue(String line, String delimiter, Map mo) throws Exception {
553 String[] elems = splitAssignment(line, delimiter);
554
555 mo.put(elems[0], elems[1]);
556 }
557
558 private void parseLine(String line, Map mo) throws Exception {
559
560 switch (getLineType(line)) {
561 case TYPE_VARIABLE_ASSIGNMENT:
562 parseVariableAssignment(line, mo);
563 break;
564 case TYPE_STATEMENT:
565 case TYPE_FLAG:
566 // for now ignore statements
567 break;
568 case TYPE_UNKNOWN:
569 // we'll gloss over unknown lines as well;
570 break;
571 default:
572 throw new Exception("Unable to parse line: " + line);
573 }
574 }
575
576 private void parseVariableAssignment(String line, Map mo) throws Exception {
577 if (line.contains("?=")) {
578 parseConditionalAssignment(line, mo);
579 } else if (line.contains("+=")) {
580 parseAdditiveAssignment(line, "+=", mo);
581 } else if (line.contains("=+")) {
582 parseAdditiveAssignment(line, "=+", mo);
583 } else if (line.contains(":=")) {
584 parseImmediateAssignment(line, ":=", mo);
585 } else {
586 parseKeyValue(line, "=", mo);
587 }
588
589 }
590
591 private List parseVars(String line) {
592 List l = new ArrayList();
593
594 int i = 0;
595
596 while ((i = line.indexOf("${", i)) > -1) {
597 int i2 = line.indexOf("}", i);
598
599 l.add(line.subSequence(i + 2, i2));
600 i++;
601 }
602
603 return l;
604 }
605
606 public Object put(Object arg0, Object arg1) {
607 throw new RuntimeException("BB configuration is read-only.");
608 }
609
610 public void putAll(Map arg0) {
611 throw new RuntimeException("BB configuration is read-only.");
612 }
613
614 public Object remove(Object arg0) {
615 throw new RuntimeException("BB configuration is read-only.");
616 }
617
618 private String removeQuotes(String line) {
619 line = line.trim();
620
621 if (line.startsWith("\"")) {
622 line = line.substring(1);
623 }
624
625 if (line.endsWith("\"")) {
626 line = line.substring(0, line.length() - 1);
627 }
628
629 return line;
630 }
631
632 public int size() {
633 try {
634 checkValidAndLock(true);
635 return properties.size();
636 }catch (Exception e) {
637 e.printStackTrace();
638 return 0;
639 }finally {
640 rlock.unlock();
641 }
642 }
643
644 private String[] splitAssignment(String line, String seperator) throws Exception {
645 String[] elems = line.split(seperator);
646
647 if (elems.length < 2) {
648 throw new Exception("Unable to parse assignment in line: " + line);
649 } else if (elems.length == 2) {
650
651 elems[0] = elems[0].trim(); // Clean up trailing or leading spaces.
652 if (elems[0].startsWith("export ")) {
653 elems[0] = elems[0].substring("export ".length()).trim();
654 }
655 elems[1] = removeQuotes(elems[1]); // Evaluate variables
656
657 return elems;
658 } else {
659 String[] retVal = new String[2];
660
661 retVal[0] = elems[0];
662 if (retVal[0].startsWith("export ")) {
663 retVal[0] = retVal[0].substring("export ".length()).trim();
664 }
665 retVal[1] = appendAll(elems, 1);
666
667 return retVal;
668 }
669 }
670
671 private String stripLeading(String target, String leading) {
672 if (target.startsWith(leading)) {
673 target = target.substring(leading.length());
674 }
675
676 return target;
677 }
678
679 /**
680 * Return a string with variable substitutions in place.
681 *
682 * @param expression
683 * @return Input string with any substitutions from this file.
684 */
685 public String substitute(String expression, Map mo) {
686
687 List vars = parseVars(expression);
688
689 for (Iterator i = vars.iterator(); i.hasNext();) {
690 String varName = (String) i.next();
691 String varToken = "${" + varName + "}";
692
693 if (mo.containsKey(varName)) {
694 expression = expression.replace(varToken, (String) mo.get(varName));
695 } else if (System.getProperty(varName) != null) {
696 expression = expression.replace(varToken, System.getProperty(varName));
697 } else if (varName.toUpperCase().equals("HOME")) {
698 expression = expression.replace(varToken, System.getProperty("user.home"));
699 }
700 }
701
702 return expression;
703 }
704
705 public Collection values() {
706 try {
707 checkValidAndLock(true);
708 return properties.values();
709 } catch (Exception e) {
710 e.printStackTrace();
711 return null;
712 }finally {
713 rlock.unlock();
714 }
715 }
716
717 public void changeNotified(IResource[] added, IResource[] removed, IResource[] changed) {
718 wlock.lock();
719 try {
720 if (initialized && (removed != null || changed != null)) {
721 for(int i=0;removed != null && i<removed.length;i++) {
722 if (this.depends.contains(removed[i].getLocation().toString())) {
723 initialized = false;
724 return;
725 }
726 }
727 for(int i=0;changed != null && i<changed.length;i++) {
728 if (this.depends.contains(changed[i].getLocation().toString())) {
729 initialized = false;
730 return;
731 }
732 }
733 }
734 }
735 finally {
736 wlock.unlock();
737 }
738 }
739}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/IBBSessionListener.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/IBBSessionListener.java
new file mode 100644
index 0000000..4d0054f
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/IBBSessionListener.java
@@ -0,0 +1,18 @@
1/*******************************************************************************
2 * Copyright (c) 2012 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11
12package org.yocto.bc.bitbake;
13
14import org.eclipse.core.resources.IResource;
15
16public interface IBBSessionListener {
17 public void changeNotified(IResource[] added, IResource[] removed, IResource[] changed);
18}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ICommandResponseHandler.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ICommandResponseHandler.java
new file mode 100644
index 0000000..4c44352
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ICommandResponseHandler.java
@@ -0,0 +1,15 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13public interface ICommandResponseHandler {
14 public void response(String line, boolean isError);
15}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ProjectInfoHelper.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ProjectInfoHelper.java
new file mode 100644
index 0000000..25dac97
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ProjectInfoHelper.java
@@ -0,0 +1,105 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13import java.io.BufferedReader;
14import java.io.File;
15import java.io.FileOutputStream;
16import java.io.FileReader;
17import java.io.IOException;
18
19import org.eclipse.core.resources.IProject;
20import org.eclipse.core.resources.ResourcesPlugin;
21
22import org.yocto.bc.ui.model.ProjectInfo;
23
24/**
25 * A helper class for ProjectInfo related tasks.
26 *
27 * @author kgilmer
28 *
29 */
30public class ProjectInfoHelper {
31
32 protected static final String DEFAULT_INIT_SCRIPT = "oe-init-build-env";
33 /**
34 * @param path
35 * @return The path to bitbake init script
36 * @throws IOException
37 */
38 public static String getInitScriptPath(String path) throws IOException {
39 String val = path + File.separator + DEFAULT_INIT_SCRIPT;
40
41 File inFile = new File(path, ".eclipse-data");
42 if(inFile.exists()) {
43 BufferedReader br = new BufferedReader(new FileReader(inFile));
44 val = br.readLine();
45 br.close();
46 }
47
48 return val;
49 }
50
51 public static String getInitScript(String path) throws IOException {
52 File inFile = new File(path);
53 BufferedReader br = new BufferedReader(new FileReader(inFile));
54 StringBuffer sb = new StringBuffer();
55 String line = null;
56
57 while ((line = br.readLine()) != null) {
58 sb.append(line);
59 }
60
61 br.close();
62
63 return sb.toString();
64 }
65
66 public static String getProjectName(String projectRoot) {
67 IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
68 for (int i = 0; i < projects.length; ++i) {
69 try {
70 if (projects[i].getLocationURI().getPath().equals(projectRoot)) {
71 return projects[i].getName();
72 }
73
74 } catch (Exception e) {
75 // TODO Auto-generated catch block
76 e.printStackTrace();
77 }
78 }
79
80 return null;
81 }
82
83 /**
84 * This method will store the path to the bitbake init script for future
85 * reference.
86 *
87 * @param path
88 * @param projInfo
89 * @throws IOException
90 */
91 public static void store(String path, ProjectInfo projInfo) throws IOException {
92 writeToFile(path, projInfo.getInitScriptPath());
93 }
94
95 private static void writeToFile(String path, String init) throws IOException {
96 File outFile = new File(path, ".eclipse-data");
97 FileOutputStream fos = new FileOutputStream(outFile);
98
99 fos.write(init.getBytes());
100
101 fos.flush();
102 fos.close();
103 }
104
105}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java
new file mode 100644
index 0000000..4719865
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/bitbake/ShellSession.java
@@ -0,0 +1,248 @@
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 *******************************************************************************/
11package org.yocto.bc.bitbake;
12
13import java.io.BufferedReader;
14import java.io.File;
15import java.io.IOException;
16import java.io.InputStream;
17import java.io.InputStreamReader;
18import java.io.OutputStream;
19import java.io.Writer;
20
21/**
22 * A class for Linux shell sessions.
23 * @author kgilmer
24 *
25 */
26public class ShellSession {
27 /**
28 * Bash shell
29 */
30 public static final int SHELL_TYPE_BASH = 1;
31 /**
32 * sh shell
33 */
34 public static final int SHELL_TYPE_SH = 2;
35 private volatile boolean interrupt = false;
36 /**
37 * String used to isolate command execution
38 */
39 public static final String TERMINATOR = "#234o987dsfkcqiuwey18837032843259d";
40 public static final String LT = System.getProperty("line.separator");
41
42 public static String getFilePath(String file) throws IOException {
43 File f = new File(file);
44
45 if (!f.exists() || f.isDirectory()) {
46 throw new IOException("Path passed is not a file: " + file);
47 }
48
49 StringBuffer sb = new StringBuffer();
50
51 String elems[] = file.split(File.separator);
52
53 for (int i = 0; i < elems.length - 1; ++i) {
54 sb.append(elems[i]);
55 sb.append(File.separator);
56 }
57
58 return sb.toString();
59 }
60 private Process process;
61
62 private OutputStream pos = null;
63 //private File initFile = null;
64 private String shellPath = null;
65 private final String initCmd;
66 private final File root;
67 private final Writer out;
68
69
70 public ShellSession(int shellType, File root, String initCmd, Writer out) throws IOException {
71 this.root = root;
72 this.initCmd = initCmd;
73 if (out == null) {
74 this.out = new NullWriter();
75 } else {
76 this.out = out;
77 }
78 if (shellType == SHELL_TYPE_SH) {
79 shellPath = "/bin/sh";
80 }
81 shellPath = "/bin/bash";
82
83 initializeShell();
84 }
85
86 private void initializeShell() throws IOException {
87 process = Runtime.getRuntime().exec(shellPath);
88 pos = process.getOutputStream();
89
90 if (root != null) {
91 out.write(execute("cd " + root.getAbsolutePath()));
92 }
93
94 if (initCmd != null) {
95 out.write(execute("source " + initCmd));
96 }
97 }
98
99 synchronized
100 public String execute(String command) throws IOException {
101 return execute(command, (int [])null);
102 }
103
104 synchronized
105 public String execute(String command, int[] retCode) throws IOException {
106 String errorMessage = null;
107 interrupt = false;
108 out.write(command);
109 out.write(LT);
110
111 sendToProcessAndTerminate(command);
112
113 if (process.getErrorStream().available() > 0) {
114 byte[] msg = new byte[process.getErrorStream().available()];
115
116 process.getErrorStream().read(msg, 0, msg.length);
117 out.write(new String(msg));
118 out.write(LT);
119 errorMessage = "Error while executing: " + command + LT + new String(msg);
120 }
121
122 BufferedReader br = new BufferedReader(new InputStreamReader(process
123 .getInputStream()));
124
125 StringBuffer sb = new StringBuffer();
126 String line = null;
127
128 while (((line = br.readLine()) != null) && !line.endsWith(TERMINATOR) && !interrupt) {
129 sb.append(line);
130 sb.append(LT);
131 out.write(line);
132 out.write(LT);
133 }
134
135 if (interrupt) {
136 process.destroy();
137 initializeShell();
138 interrupt = false;
139 }else if (line != null && retCode != null) {
140 try {
141 retCode[0]=Integer.parseInt(line.substring(0,line.lastIndexOf(TERMINATOR)));
142 }catch (NumberFormatException e) {
143 throw new IOException("Can NOT get return code" + command + LT + line);
144 }
145 }
146
147 if (errorMessage != null) {
148 throw new IOException(errorMessage);
149 }
150
151 return sb.toString();
152 }
153
154synchronized
155 public void execute(String command, ICommandResponseHandler handler) throws IOException {
156 System.out.println(command);
157 execute(command, TERMINATOR, handler);
158 }
159
160 synchronized
161 public void execute(String command, String terminator, ICommandResponseHandler handler) throws IOException {
162 interrupt = false;
163 InputStream errIs = process.getErrorStream();
164 if (errIs.available() > 0) {
165 clearErrorStream(errIs);
166 }
167 sendToProcessAndTerminate(command);
168
169 BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
170 String std = null;
171
172 do {
173 if (errIs.available() > 0) {
174 byte[] msg = new byte[errIs.available()];
175
176 errIs.read(msg, 0, msg.length);
177 out.write(new String(msg));
178 handler.response(new String(msg), true);
179 }
180
181 std = br.readLine();
182
183 if (std != null && !std.endsWith(terminator)) {
184 out.write(std);
185 handler.response(std, false);
186 }
187
188 } while (std != null && !std.endsWith(terminator) && !interrupt);
189
190 if (interrupt) {
191 process.destroy();
192 initializeShell();
193 interrupt = false;
194 }
195 }
196
197 private void clearErrorStream(InputStream is) {
198
199 try {
200 byte b[] = new byte[is.available()];
201 is.read(b);
202 System.out.println("clearing: " + new String(b));
203 } catch (IOException e) {
204 e.printStackTrace();
205 //Ignore any error
206 }
207 }
208
209 /**
210 * Send command string to shell process and add special terminator string so
211 * reader knows when output is complete.
212 *
213 * @param command
214 * @throws IOException
215 */
216 private void sendToProcessAndTerminate(String command) throws IOException {
217 pos.write(command.getBytes());
218 pos.write(LT.getBytes());
219 pos.flush();
220 pos.write("echo $?".getBytes());
221 pos.write(TERMINATOR.getBytes());
222 pos.write(LT.getBytes());
223 pos.flush();
224 }
225
226 /**
227 * Interrupt any running processes.
228 */
229 public void interrupt() {
230 interrupt = true;
231 }
232
233 private class NullWriter extends Writer {
234
235 @Override
236 public void close() throws IOException {
237 }
238
239 @Override
240 public void flush() throws IOException {
241 }
242
243 @Override
244 public void write(char[] cbuf, int off, int len) throws IOException {
245 }
246
247 }
248}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/Activator.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/Activator.java
new file mode 100644
index 0000000..505a254
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/Activator.java
@@ -0,0 +1,266 @@
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 *******************************************************************************/
11package org.yocto.bc.ui;
12
13import java.io.File;
14import java.io.IOException;
15import java.io.Writer;
16import java.lang.reflect.InvocationTargetException;
17import java.util.Hashtable;
18import java.util.Iterator;
19import java.util.Map;
20
21import org.eclipse.core.resources.IProject;
22import org.eclipse.core.resources.IResource;
23import org.eclipse.core.resources.IResourceChangeEvent;
24import org.eclipse.core.resources.IResourceChangeListener;
25import org.eclipse.core.resources.ResourcesPlugin;
26import org.eclipse.core.runtime.CoreException;
27import org.eclipse.jface.resource.ImageDescriptor;
28import org.eclipse.jface.resource.ImageRegistry;
29import org.eclipse.ui.plugin.AbstractUIPlugin;
30import org.osgi.framework.BundleContext;
31
32import org.yocto.bc.bitbake.BBRecipe;
33import org.yocto.bc.bitbake.BBSession;
34import org.yocto.bc.bitbake.ProjectInfoHelper;
35import org.yocto.bc.bitbake.ShellSession;
36import org.yocto.bc.ui.model.ProjectInfo;
37import org.yocto.bc.ui.wizards.newproject.CreateBBCProjectOperation;
38
39public class Activator extends AbstractUIPlugin {
40
41 // The plug-in ID
42 public static final String PLUGIN_ID = "org.yocto.bc.ui";
43 public static final String IMAGE_VARIABLE = "IMAGE_VARIABLE";
44 public static final String IMAGE_FUNCTION = "IMAGE_FUNCTION";
45
46 // The shared instance
47 private static Activator plugin;
48 private static Map shellMap;
49 private static Map projInfoMap;
50 private static Hashtable bbSessionMap;
51 private static Hashtable bbRecipeMap;
52
53 private IResourceChangeListener listener = new BCResourceChangeListener();
54
55 public static BBRecipe getBBRecipe(BBSession session, String filePath) throws IOException {
56 if (bbRecipeMap == null) {
57 bbRecipeMap = new Hashtable();
58 }
59
60 String key = session.getProjInfoRoot() + filePath;
61 BBRecipe recipe = (BBRecipe) bbRecipeMap.get(key);
62 if (recipe == null) {
63 recipe = new BBRecipe(session,filePath);
64 bbRecipeMap.put(key, recipe);
65 }
66
67 return recipe;
68 }
69
70 /**
71 * Get or create a BitBake session passing in ProjectInfo
72 * @param pinfo
73 * @return
74 * @throws IOException
75 */
76 public static BBSession getBBSession(String projectRoot, Writer out) throws IOException {
77 if (bbSessionMap == null) {
78 bbSessionMap = new Hashtable();
79 }
80
81 BBSession bbs = (BBSession) bbSessionMap.get(projectRoot);
82
83 if (bbs == null) {
84 bbs = new BBSession(getShellSession(projectRoot, out), projectRoot);
85 bbSessionMap.put(projectRoot, bbs);
86 }
87
88 return bbs;
89 }
90
91 /**
92 * Get or create a BitBake session passing in ProjectInfo
93 * @param pinfo
94 * @return
95 * @throws IOException
96 */
97 public static BBSession getBBSession(String projectRoot) throws IOException {
98 if (bbSessionMap == null) {
99 bbSessionMap = new Hashtable();
100 }
101
102 BBSession bbs = (BBSession) bbSessionMap.get(projectRoot);
103
104 if (bbs == null) {
105 bbs = new BBSession(getShellSession(projectRoot, null), projectRoot);
106 bbSessionMap.put(projectRoot, bbs);
107 }
108
109 return bbs;
110 }
111
112 /**
113 * Returns the shared instance
114 *
115 * @return the shared instance
116 */
117 public static Activator getDefault() {
118 return plugin;
119 }
120
121 /**
122 * Returns an image descriptor for the image file at the given
123 * plug-in relative path
124 *
125 * @param path the path
126 * @return the image descriptor
127 */
128 public static ImageDescriptor getImageDescriptor(String path) {
129 return imageDescriptorFromPlugin(PLUGIN_ID, path);
130 }
131
132 public static ProjectInfo getProjInfo(String location) throws CoreException, InvocationTargetException, InterruptedException {
133 if (projInfoMap == null) {
134 projInfoMap = new Hashtable();
135 }
136
137 ProjectInfo pi = (ProjectInfo) projInfoMap.get(location);
138
139 if (pi == null) {
140 pi = new ProjectInfo();
141 pi.setLocation(location);
142 try {
143 pi.setInitScriptPath(ProjectInfoHelper.getInitScriptPath(location));
144 } catch (IOException e) {
145 throw new InvocationTargetException(e);
146 }
147 }
148
149 return pi;
150 }
151
152 public static void notifyAllBBSession(IResource[] added, IResource[] removed, IResource[] changed) {
153 Iterator iter;
154 if(bbRecipeMap != null) {
155 iter = bbRecipeMap.values().iterator();
156 while(iter.hasNext()) {
157 BBRecipe p = (BBRecipe)iter.next();
158 p.changeNotified(added, removed, changed);
159 }
160 }
161
162 if(bbSessionMap != null) {
163 iter= bbSessionMap.values().iterator();
164 while(iter.hasNext()) {
165 BBSession p = (BBSession)iter.next();
166 p.changeNotified(added, removed, changed);
167 }
168 }
169 }
170
171 /**
172 * @param absolutePath
173 * @return a cached shell session for a given project root.
174 * @throws IOException
175 */
176 private static ShellSession getShellSession(String absolutePath, Writer out) throws IOException {
177 if (shellMap == null) {
178 shellMap = new Hashtable();
179 }
180
181 ShellSession ss = (ShellSession) shellMap.get(absolutePath);
182
183 if (ss == null) {
184 ss = new ShellSession(ShellSession.SHELL_TYPE_BASH, new File(absolutePath), ProjectInfoHelper.getInitScriptPath(absolutePath), out);
185 }
186
187 return ss;
188 }
189
190 private static String loadInit(String absolutePath) throws CoreException {
191 IProject [] prjs = ResourcesPlugin.getWorkspace().getRoot().getProjects();
192 IProject foundPrj = null;
193
194 for (int i = 0; i < prjs.length; ++i) {
195 IProject p = prjs[i];
196
197 System.out
198 .println(p.getDescription().getLocationURI().getPath());
199
200 if (p.getDescription().getLocationURI().getPath().equals(absolutePath)) {
201 foundPrj = p;
202 break;
203 }
204 }
205
206 if (foundPrj == null) {
207 throw new RuntimeException("Unable to find project associated with path! " + absolutePath);
208 }
209
210 return foundPrj.getPersistentProperty(CreateBBCProjectOperation.BBC_PROJECT_INIT);
211 }
212
213 public static void putProjInfo(String location, ProjectInfo pinfo) {
214 if (projInfoMap == null) {
215 projInfoMap = new Hashtable();
216 }
217
218
219
220 projInfoMap.put(location, pinfo);
221 }
222
223 /**
224 * The constructor
225 */
226 public Activator() {
227 }
228
229 /*
230 * (non-Javadoc)
231 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
232 */
233 @Override
234 public void start(BundleContext context) throws Exception {
235 super.start(context);
236 plugin = this;
237 ResourcesPlugin.getWorkspace().addResourceChangeListener(
238 listener, IResourceChangeEvent.POST_CHANGE);
239 }
240
241 /*
242 * (non-Javadoc)
243 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
244 */
245 @Override
246 public void stop(BundleContext context) throws Exception {
247 ResourcesPlugin.getWorkspace().removeResourceChangeListener(
248 listener);
249 plugin = null;
250 super.stop(context);
251 }
252
253 /**
254 * Reset a configuration
255 * @param path
256 */
257 public static void resetBBSession(String path) {
258 shellMap.remove(path);
259 bbSessionMap.remove(path);
260 }
261
262 protected void initializeImageRegistry(ImageRegistry reg) {
263 reg.put(IMAGE_VARIABLE, Activator.getImageDescriptor("icons/variable.gif"));
264 reg.put(IMAGE_FUNCTION, Activator.getImageDescriptor("icons/function.gif"));
265 }
266}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/BCResourceChangeListener.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/BCResourceChangeListener.java
new file mode 100644
index 0000000..8a2bfdd
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/BCResourceChangeListener.java
@@ -0,0 +1,64 @@
1package org.yocto.bc.ui;
2
3import java.util.HashSet;
4
5import org.eclipse.core.resources.IFile;
6import org.eclipse.core.resources.IProject;
7import org.eclipse.core.resources.IResourceChangeEvent;
8import org.eclipse.core.resources.IResourceChangeListener;
9import org.eclipse.core.resources.IResource;
10import org.eclipse.core.resources.IResourceDelta;
11import org.eclipse.core.resources.IResourceDeltaVisitor;
12import org.eclipse.core.runtime.*;
13import org.yocto.bc.ui.builder.BitbakeCommanderNature;
14
15public class BCResourceChangeListener implements IResourceChangeListener {
16
17 public void resourceChanged(IResourceChangeEvent event) {
18 final HashSet<IResource> removed = new HashSet<IResource>();
19 final HashSet<IResource> changed = new HashSet<IResource>();
20 switch (event.getType()) {
21 case IResourceChangeEvent.POST_CHANGE:
22 try {
23 event.getDelta().accept(new IResourceDeltaVisitor() {
24 public boolean visit(IResourceDelta delta) throws CoreException {
25 IResource res = delta.getResource();
26 Boolean visit= true;
27 if (res instanceof IProject) {
28 visit = false;
29 try {
30 if(((IProject) res).isOpen() &&
31 ((IProject) res).hasNature(BitbakeCommanderNature.NATURE_ID)){
32 visit = true;
33 }
34 }catch (CoreException e) {
35 }
36 }
37 if (visit && (res instanceof IFile))
38 {
39 switch (delta.getKind()) {
40 case IResourceDelta.REMOVED:
41 removed.add(res);
42 break;
43 case IResourceDelta.CHANGED:
44 changed.add(res);
45 break;
46 }
47 }
48 return visit; // visit the children
49 }
50 });
51 //notify all the sessions
52 Activator.notifyAllBBSession(null,
53 removed.toArray(new IResource[removed.size()]),
54 changed.toArray(new IResource[changed.size()]));
55
56 }catch (CoreException e) {
57 e.printStackTrace();
58 }
59 break;
60 default:
61 break;
62 }
63 }
64}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/AbstractBitbakeCommandAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/AbstractBitbakeCommandAction.java
new file mode 100644
index 0000000..41d5c73
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/AbstractBitbakeCommandAction.java
@@ -0,0 +1,199 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import java.io.IOException;
14
15import org.eclipse.core.resources.IFile;
16import org.eclipse.core.resources.IProject;
17import org.eclipse.core.runtime.CoreException;
18import org.eclipse.core.runtime.IProgressMonitor;
19import org.eclipse.core.runtime.IStatus;
20import org.eclipse.core.runtime.Status;
21import org.eclipse.core.runtime.jobs.Job;
22import org.eclipse.jface.action.IAction;
23import org.eclipse.jface.preference.JFacePreferences;
24import org.eclipse.jface.resource.JFaceResources;
25import org.eclipse.jface.viewers.ISelection;
26import org.eclipse.jface.viewers.IStructuredSelection;
27import org.eclipse.swt.graphics.Color;
28import org.eclipse.ui.IWorkbenchWindow;
29import org.eclipse.ui.IWorkbenchWindowActionDelegate;
30import org.eclipse.ui.console.MessageConsole;
31import org.eclipse.ui.console.MessageConsoleStream;
32
33import org.yocto.bc.bitbake.BBLanguageHelper;
34import org.yocto.bc.bitbake.BBSession;
35import org.yocto.bc.bitbake.ICommandResponseHandler;
36import org.yocto.bc.ui.Activator;
37import org.yocto.bc.ui.builder.BitbakeCommanderNature;
38
39public abstract class AbstractBitbakeCommandAction implements IWorkbenchWindowActionDelegate {
40
41 private class CommandJob extends Job {
42
43 public CommandJob() {
44 super(getJobTitle());
45 }
46
47 @Override
48 protected IStatus run(IProgressMonitor monitor) {
49 String cmds[] = getCommands();
50 return execCommands(cmds, monitor);
51 }
52
53 }
54 protected IAction action;
55 protected IFile recipe;
56 protected BBSession bbs;
57
58 private Color commandColor, responseColor, errorColor;
59 private boolean errorOccurred = false;
60
61 public AbstractBitbakeCommandAction() {
62 commandColor = JFaceResources.getColorRegistry().get(JFacePreferences.ACTIVE_HYPERLINK_COLOR);
63 responseColor = JFaceResources.getColorRegistry().get(JFacePreferences.HYPERLINK_COLOR);
64 errorColor = JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR);
65 }
66
67 private void checkEnabled(IFile file) {
68 try {
69 if (file.getFileExtension() == null || !file.getFileExtension().equals(BBLanguageHelper.BITBAKE_RECIPE_FILE_EXTENSION)) {
70 action.setEnabled(false);
71 return;
72 }
73
74 IProject project = file.getProject();
75 if (!(project.hasNature(BitbakeCommanderNature.NATURE_ID))) {
76 action.setEnabled(false);
77 return;
78 }
79
80 bbs = Activator.getBBSession(project.getLocationURI().getPath());
81
82 if (bbs != null) {
83 recipe = file;
84 action.setEnabled(true);
85 }
86
87 } catch (CoreException e) {
88 action.setEnabled(false);
89 e.printStackTrace();
90 } catch (Exception e) {
91 action.setEnabled(false);
92 e.printStackTrace();
93 }
94 }
95
96 public void dispose() {
97 }
98
99 /**
100 * Execute array of commands with bitbake and put output in console.
101 *
102 * @param cmds
103 * @param monitor
104 * @return
105 */
106 protected IStatus execCommands(String[] cmds, final IProgressMonitor monitor) {
107 MessageConsole mc = bbs.getConsole();
108 final MessageConsoleStream cmd = mc.newMessageStream();
109 cmd.setColor(commandColor);
110 final MessageConsoleStream out = mc.newMessageStream();
111 final MessageConsoleStream err = mc.newMessageStream();
112 err.setColor(errorColor);
113
114 try {
115 for (int i = 0; i < cmds.length; ++i) {
116 cmd.println(cmds[i]);
117 monitor.subTask(cmds[i]);
118 bbs.getShell().execute(cmds[i], new ICommandResponseHandler() {
119
120 public void response(String line, boolean isError) {
121 if (monitor.isCanceled()) {
122 cmd.println("Interrupting process by user request.");
123 bbs.getShell().interrupt();
124 }
125
126 if (isError) {
127 err.println(line);
128 errorOccurred();
129 } else if (line.startsWith("ERROR:")) {
130 err.println(line);
131 } else {
132 out.println(line);
133 }
134 }
135 });
136 }
137 } catch (IOException e) {
138 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
139 } finally {
140 try {
141 if (errorOccurred) {
142 cmd.println("At least one error occured while executing this command. Check output for more details.");
143 }
144 cmd.close();
145 out.close();
146 err.close();
147 } catch (IOException e) {
148 e.printStackTrace();
149 }
150 }
151
152 return Status.OK_STATUS;
153 }
154
155 protected void errorOccurred() {
156 errorOccurred = true;
157 }
158
159 /**
160 * Return the command to be executed.
161 *
162 * @return
163 */
164 public abstract String[] getCommands();
165
166 public Job getJob() {
167 return new CommandJob();
168 }
169
170 /**
171 * Return the title of the job.
172 *
173 * @return
174 */
175 public abstract String getJobTitle();
176
177 public void init(IWorkbenchWindow window) {
178 }
179
180 public void run(IAction action) {
181 Job job = getJob();
182 job.schedule();
183 }
184
185 public void selectionChanged(IAction action, ISelection selection) {
186 this.action = action;
187 if (selection instanceof IStructuredSelection) {
188 Object sel = ((IStructuredSelection) selection).getFirstElement();
189
190 if (sel instanceof IFile) {
191 checkEnabled((IFile) sel);
192 return;
193 }
194 }
195
196 action.setEnabled(false);
197 }
198
199} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeBuildRecipeAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeBuildRecipeAction.java
new file mode 100644
index 0000000..22ac94c
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeBuildRecipeAction.java
@@ -0,0 +1,24 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13public class BitbakeBuildRecipeAction extends AbstractBitbakeCommandAction {
14
15 @Override
16 public String [] getCommands() {
17 return new String[] {"bitbake -b " + recipe.getLocationURI().getPath()};
18 }
19
20 @Override
21 public String getJobTitle() {
22 return "Building " + recipe.getName();
23 }
24} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeCleanRecipeAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeCleanRecipeAction.java
new file mode 100644
index 0000000..f95117e
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeCleanRecipeAction.java
@@ -0,0 +1,26 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13public class BitbakeCleanRecipeAction extends AbstractBitbakeCommandAction {
14
15 @Override
16 public String [] getCommands() {
17 return new String[] {"bitbake -c clean -b " + recipe.getLocationURI().getPath()};
18 }
19
20 @Override
21 public String getJobTitle() {
22 return "Cleaning " + recipe.getName();
23 }
24
25
26} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeImportAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeImportAction.java
new file mode 100644
index 0000000..ecceecf
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeImportAction.java
@@ -0,0 +1,106 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import java.io.File;
14
15import org.eclipse.core.resources.IProject;
16import org.eclipse.core.resources.IProjectDescription;
17import org.eclipse.core.resources.IResource;
18import org.eclipse.core.resources.IWorkspaceRoot;
19import org.eclipse.core.resources.ResourcesPlugin;
20import org.eclipse.core.runtime.IProgressMonitor;
21import org.eclipse.core.runtime.IStatus;
22import org.eclipse.core.runtime.Status;
23import org.eclipse.core.runtime.jobs.Job;
24
25import org.yocto.bc.bitbake.BBCommonVars;
26import org.yocto.bc.bitbake.BBRecipe;
27import org.yocto.bc.ui.Activator;
28
29public class BitbakeImportAction extends AbstractBitbakeCommandAction {
30
31 private class ImportJob extends Job {
32
33 public ImportJob() {
34 super(getJobTitle());
35 }
36
37 @Override
38 protected IStatus run(IProgressMonitor monitor) {
39
40 try {
41 BBRecipe br = new BBRecipe(bbs, recipe.getLocationURI().getPath());
42 br.initialize();
43 String filePath = (String) br.get(BBCommonVars.S);
44
45 //"${WORKDIR}/${PN}-${PV}"
46 if (filePath == null) {
47 filePath = ((String) br.get(BBCommonVars.WORKDIR)) + File.separator + ((String) br.get(BBCommonVars.PN)) + "-" + ((String) br.get(BBCommonVars.PV));
48 }
49
50 String projectName = (String) br.get(BBCommonVars.PN);
51
52 if (filePath == null || projectName == null) {
53 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to parse recipe file.");
54 }
55
56 File workdir = new File(filePath);
57
58 if (workdir.exists() && workdir.isFile()) {
59 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, workdir.getPath() + " is an invalid workdir.");
60 }
61
62 if (!workdir.exists()) {
63 execCommands(new String[] {"bitbake -c patch -b " + recipe.getLocationURI().getPath()}, monitor);
64 }
65
66 if (!workdir.exists()) {
67 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to retrieve sources from BitBake. Consult console.");
68 }
69
70 IProjectDescription desc = ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
71 IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot();
72 IProject proj = wsroot.getProject(projectName);
73 proj.create(desc, monitor);
74 proj.open(monitor);
75
76 String copyCmd = "cp -r " + workdir.getAbsolutePath() + File.separator + "* \"" + proj.getLocationURI().getPath() + "\"";
77 execCommands(new String[] {copyCmd} , monitor);
78
79 proj.refreshLocal(IResource.DEPTH_INFINITE, monitor);
80
81 } catch (Exception e) {
82 e.printStackTrace();
83 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to create project.", e);
84 }
85
86 return Status.OK_STATUS;
87 }
88
89 }
90
91 @Override
92 public String [] getCommands() {
93 return null;
94 }
95
96
97 @Override
98 public Job getJob() {
99 return new ImportJob();
100 }
101
102 @Override
103 public String getJobTitle() {
104 return "Importing " + recipe.getName();
105 }
106} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeRebuildRecipeAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeRebuildRecipeAction.java
new file mode 100644
index 0000000..c5dedea
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/BitbakeRebuildRecipeAction.java
@@ -0,0 +1,29 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13/**
14 * Rebuild a recipe.
15 * @author kgilmer
16 *
17 */
18public class BitbakeRebuildRecipeAction extends AbstractBitbakeCommandAction {
19
20 @Override
21 public String [] getCommands() {
22 return new String[] {"bitbake -c rebuild -b " + recipe.getLocationURI().getPath()};
23 }
24
25 @Override
26 public String getJobTitle() {
27 return "Rebuilding " + recipe.getName();
28 }
29} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobAction.java
new file mode 100644
index 0000000..e92fac0
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobAction.java
@@ -0,0 +1,84 @@
1/*******************************************************************************
2 * Copyright (c) 2011 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import org.eclipse.ui.PlatformUI;
14import org.eclipse.ui.IWorkbench;
15import org.eclipse.ui.IWorkbenchPage;
16import org.eclipse.ui.IWorkbenchWindow;
17
18import org.eclipse.core.resources.IProject;
19import org.eclipse.core.resources.IResource;
20import org.eclipse.core.runtime.IAdaptable;
21import org.eclipse.jface.action.IAction;
22import org.eclipse.jface.viewers.ISelection;
23import org.eclipse.jface.viewers.IStructuredSelection;
24
25import org.eclipse.swt.widgets.Shell;
26
27import org.yocto.bc.ui.builder.BitbakeCommanderNature;
28
29
30public class LaunchHobAction {
31 private static final String DIALOG_TITLE = "Launch HOB";
32
33 public void run(IAction action) {
34 IResource resource = getSelectedResource();
35 if (resource == null)
36 return;
37
38 IProject project = resource.getProject();
39 LaunchHobDialog hobDialog = new LaunchHobDialog(new Shell(), DIALOG_TITLE, project);
40 hobDialog.open();
41 String buildDir = hobDialog.getBuildDir();
42
43 if (buildDir != null) {
44 try {
45 BitbakeCommanderNature.launchHob(project,buildDir);
46 } catch (Exception e){
47 System.out.println(e.getMessage());
48 }
49 }
50
51 }
52
53 public void dispose() {
54
55 }
56
57 private IResource getSelectedResource() {
58 IWorkbench iworkbench = PlatformUI.getWorkbench();
59 if (iworkbench == null){
60 return null;
61 }
62 IWorkbenchWindow iworkbenchwindow = iworkbench.getActiveWorkbenchWindow();
63 if (iworkbenchwindow == null) {
64 return null;
65 }
66 IWorkbenchPage iworkbenchpage = iworkbenchwindow.getActivePage();
67 if (iworkbenchpage == null) {
68 return null;
69 }
70 ISelection sel = iworkbenchpage.getSelection();
71
72 if (!(sel instanceof IStructuredSelection))
73 return null;
74 IStructuredSelection ss = (IStructuredSelection) sel;
75 Object element = ss.getFirstElement();
76 if (element instanceof IResource)
77 return (IResource) element;
78 if (!(element instanceof IAdaptable))
79 return null;
80 IAdaptable adaptable = (IAdaptable)element;
81 Object adapter = adaptable.getAdapter(IResource.class);
82 return (IResource) adapter;
83 }
84}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobDialog.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobDialog.java
new file mode 100644
index 0000000..861360d
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobDialog.java
@@ -0,0 +1,328 @@
1/*******************************************************************************
2 * Copyright (c) 2011 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import java.util.Map;
14import java.util.Iterator;
15import java.util.Map.Entry;
16import java.util.ArrayList;
17import java.util.HashMap;
18import java.util.HashSet;
19import java.io.File;
20import java.io.IOException;
21
22import org.eclipse.jface.dialogs.Dialog;
23import org.eclipse.jface.dialogs.IDialogConstants;
24
25import org.eclipse.swt.SWT;
26import org.eclipse.swt.events.ModifyEvent;
27import org.eclipse.swt.events.ModifyListener;
28import org.eclipse.swt.events.SelectionAdapter;
29import org.eclipse.swt.events.SelectionEvent;
30import org.eclipse.swt.events.SelectionListener;
31import org.eclipse.swt.layout.GridData;
32import org.eclipse.swt.layout.GridLayout;
33import org.eclipse.swt.widgets.Button;
34import org.eclipse.swt.widgets.Combo;
35import org.eclipse.swt.widgets.Composite;
36import org.eclipse.swt.widgets.Control;
37import org.eclipse.swt.widgets.DirectoryDialog;
38import org.eclipse.swt.widgets.Display;
39import org.eclipse.swt.widgets.Label;
40import org.eclipse.swt.widgets.MessageBox;
41import org.eclipse.swt.widgets.Shell;
42import org.eclipse.swt.widgets.Widget;
43
44import org.eclipse.core.resources.IProject;
45import org.eclipse.core.resources.IProjectDescription;
46import org.eclipse.core.resources.ICommand;
47
48import org.yocto.bc.ui.builder.BitbakeBuilder;
49import org.yocto.bc.ui.builder.BitbakeCommanderNature;
50
51public class LaunchHobDialog extends Dialog {
52 private String title;
53 private Button buildButton;
54 private SelectionListener fSelectionListener;
55 private ModifyListener fModifyListener;
56 private Combo build_dir_combo;
57
58 private IProject project;
59 private Shell shell;
60 private String build_dir;
61
62 public LaunchHobDialog(Shell parentShell, String dialogTitle, IProject project) {
63 super(parentShell);
64 this.shell = parentShell;
65 this.project = project;
66 this.title = dialogTitle;
67 setShellStyle(getShellStyle() | SWT.RESIZE);
68
69 fSelectionListener= new SelectionListener() {
70 public void widgetDefaultSelected(SelectionEvent e) {}
71
72 public void widgetSelected(SelectionEvent e) {
73 controlChanged(e.widget);
74 }
75 };
76
77 fModifyListener= new ModifyListener() {
78 public void modifyText(ModifyEvent e) {
79 controlModified(e.widget);
80 }
81 };
82
83 }
84
85 public String getBuildDir() {
86 return build_dir;
87 }
88 @Override
89 protected Control createDialogArea(Composite parent) {
90 final Composite result = (Composite) super.createDialogArea(parent);
91
92 try {
93 createComposite(result);
94 } catch (Exception e) {
95 // TODO Auto-generated catch block
96 System.out.println("Have you ever set the project specific Yocto Settings?");
97 System.out.println(e.getMessage());
98 }
99
100 return result;
101 }
102
103 private void createComposite(Composite composite) throws Exception{
104 Label root_label, sysroot_label;
105
106 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
107 GridLayout layout = new GridLayout(2, false);
108 composite.setLayout(layout);
109
110 gd= new GridData(SWT.FILL, SWT.CENTER, true, false);
111 gd.horizontalSpan= 2;
112 composite.setLayoutData(gd);
113
114 Label build_dir_label = new Label(composite, SWT.NONE);
115 build_dir_label.setText("Bitbake build directory: ");
116 Composite textContainer = new Composite(composite, SWT.NONE);
117 textContainer.setLayout(new GridLayout(2, false));
118 textContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
119
120 build_dir_combo = new Combo(textContainer, SWT.DROP_DOWN);
121 build_dir_combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
122 initializeBuildCombo();
123
124 Button buildButton = addDirSelectButton(textContainer, build_dir_combo);
125
126 //we add the listener at the end for avoiding the useless event trigger when control
127 //changed or modified.
128 buildButton.addSelectionListener(fSelectionListener);
129 build_dir_combo.addModifyListener(fModifyListener);
130 }
131
132 private Button addDirSelectButton(final Composite parent, final Combo combo) {
133 Button button = new Button(parent, SWT.PUSH | SWT.LEAD);
134 button.setText("Browse");
135 button.addSelectionListener(new SelectionAdapter() {
136 @Override
137 public void widgetSelected(SelectionEvent event) {
138 String dirName = new DirectoryDialog(parent.getShell()).open();
139
140 if (dirName != null) {
141 combo.add(dirName);
142 combo.setText(dirName);
143 }
144 }
145 });
146 return button;
147 }
148 @Override
149 protected void configureShell(Shell newShell) {
150 super.configureShell(newShell);
151 newShell.setText(title);
152 }
153
154 protected void buttonPressed(int buttonId) {
155 if (buttonId == IDialogConstants.OK_ID) {
156 try {
157 build_dir = build_dir_combo.getText().toString();
158 updateBuildSpec(build_dir);
159 super.buttonPressed(buttonId);
160 } catch (Exception e) {
161 // TODO Auto-generated catch block
162 System.out.println(e.getMessage());
163 }
164 }
165 else if (buttonId == IDialogConstants.CANCEL_ID)
166 {
167 super.buttonPressed(buttonId);
168 }
169 }
170
171 private boolean validateInput() {
172 boolean valid = false;
173 String build_dir = build_dir_combo.getText().toString();
174 if ((build_dir == null) || build_dir.isEmpty()) {
175 Display display = Display.getCurrent();
176 Shell shell = new Shell(display);
177 MessageBox msgBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
178 msgBox.setText("Yocto Configuration Error");
179 msgBox.setMessage("The specified build directory is empty!");
180 msgBox.open();
181 if (shell != null)
182 shell.dispose();
183 return valid;
184 }
185 String project_path = project.getLocation().toString();
186 File project_dir_file = new File(project_path);
187 File build_dir_file = new File(build_dir);
188 try {
189 if (isSubDirectory(project_dir_file, build_dir_file)) {
190 Display display = Display.getCurrent();
191 Shell shell = new Shell(display);
192 MessageBox msgBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
193 msgBox.setText("Yocto Configuration Error");
194 msgBox.setMessage("The specified build directory is a sub-dir of project path: " + project_path);
195 msgBox.open();
196 if (shell != null)
197 shell.dispose();
198 } else
199 valid = true;
200 } catch (IOException e) {
201 System.out.println(e.getMessage());
202 }
203 return valid;
204 }
205
206 private boolean isSubDirectory(File baseDir, File subDir) throws IOException {
207 baseDir = baseDir.getCanonicalFile();
208 subDir = subDir.getCanonicalFile();
209
210 File parentFile = subDir;
211 while (parentFile != null) {
212 if (baseDir.equals(parentFile)) {
213 return true;
214 }
215 parentFile = parentFile.getParentFile();
216 }
217 return false;
218 }
219
220 private void controlChanged(Widget widget) {
221
222 if (widget == buildButton)
223 {
224 }
225 }
226
227 private void controlModified(Widget widget) {
228 if (widget == build_dir_combo)
229 {
230
231 }
232 }
233
234 private void initializeBuildCombo()
235 {
236 ArrayList<String> items = new ArrayList<String> ();
237
238 try {
239 IProjectDescription desc = project.getDescription();
240
241 ICommand[] buildSpec = desc.getBuildSpec();
242 if ((buildSpec != null) && (buildSpec.length != 0))
243 {
244 for (int i = 0; i < buildSpec.length; i++) {
245 ICommand cmd = buildSpec[i];
246 if (cmd.getBuilderName().equalsIgnoreCase(BitbakeBuilder.HOB_BUILD_ID))
247 {
248 Map<String, String> args = cmd.getArguments();
249 if ((args != null) && !args.isEmpty())
250 {
251 Iterator entries = args.entrySet().iterator();
252 while (entries.hasNext()) {
253 Entry thisEntry = (Entry) entries.next();
254 String key = (String)thisEntry.getKey();
255 if (key.equalsIgnoreCase(BitbakeCommanderNature.BUILD_DIR_KEY)) {
256 build_dir_combo.removeAll();
257 build_dir_combo.setItems(getValues((String)thisEntry.getValue()));
258 }
259 }
260 }
261 }
262 }
263 }
264 } catch (Exception e) {
265 System.out.println(e.getMessage());
266 }
267 }
268
269 private String[] getValues(String value) {
270
271 if ((value != null) && !value.isEmpty())
272 {
273 String[] pieces = value.split(",");
274 for (int i = 0; i < pieces.length; i++)
275 {
276 int start = pieces[i].indexOf("[");
277 if (start >= 0)
278 pieces[i] = pieces[i].substring(start+1);
279 int end = pieces[i].indexOf("]");
280 if (end >= 0)
281 pieces[i] = pieces[i].substring(0, end);
282 pieces[i] = pieces[i].trim();
283 }
284 return pieces;
285 }
286 return null;
287 }
288
289 private void updateBuildSpec(String build_dir)
290 {
291 try {
292 String[] items = build_dir_combo.getItems();
293 HashSet values = new HashSet();
294 Map<String, String> args = new HashMap<String, String>();
295 values.add(build_dir);
296 for (int i = 0; i < items.length; i++) {
297 values.add(items[i]);
298 }
299 args.put(BitbakeCommanderNature.BUILD_DIR_KEY, values.toString());
300 IProjectDescription desc = project.getDescription();
301 ICommand[] buildSpec = desc.getBuildSpec();
302 boolean found = false;
303 if ((buildSpec != null) || (buildSpec.length != 0)) {
304 for (int i = 0; i < buildSpec.length; i++) {
305 ICommand cmd = buildSpec[i];
306 if (cmd.getBuilderName().equalsIgnoreCase(BitbakeBuilder.HOB_BUILD_ID)) {
307 cmd.setArguments(args);
308 desc.setBuildSpec(buildSpec);
309 found = true;
310 break;
311 }
312 }
313 }
314 if (!found) {
315 ICommand[] newBuildSpec = new ICommand[buildSpec.length + 1];
316 System.arraycopy(buildSpec, 0, newBuildSpec, 0, buildSpec.length);
317 ICommand cmd = desc.newCommand();
318 cmd.setBuilderName(BitbakeBuilder.HOB_BUILD_ID);
319 cmd.setArguments(args);
320 newBuildSpec[newBuildSpec.length - 1] = cmd;
321 desc.setBuildSpec(newBuildSpec);
322 }
323 project.setDescription(desc, null);
324 } catch (Exception e) {
325 System.out.println(e.getMessage());
326 }
327 }
328}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobHandler.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobHandler.java
new file mode 100644
index 0000000..002075a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchHobHandler.java
@@ -0,0 +1,50 @@
1/*******************************************************************************
2 * Copyright (c) 2011 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import org.eclipse.core.commands.ExecutionEvent;
14import org.eclipse.core.commands.ExecutionException;
15import org.eclipse.core.commands.IHandlerListener;
16import org.eclipse.core.commands.IHandler;
17
18public class LaunchHobHandler implements IHandler {
19
20 public Object execute(ExecutionEvent event) throws ExecutionException {
21 LaunchHobAction a = new LaunchHobAction();
22 a.run(null);
23 return null;
24 }
25
26 public void addHandlerListener(IHandlerListener handlerListener) {
27 // TODO Auto-generated method stub
28
29 }
30
31 public void dispose() {
32 // TODO Auto-generated method stub
33
34 }
35
36 public boolean isEnabled() {
37 // TODO Auto-generated method stub
38 return true;
39 }
40
41 public boolean isHandled() {
42 // TODO Auto-generated method stub
43 return true;
44 }
45
46 public void removeHandlerListener(IHandlerListener handlerListener) {
47 // TODO Auto-generated method stub
48
49 }
50}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewBitBakeProjectWizardAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewBitBakeProjectWizardAction.java
new file mode 100644
index 0000000..b8b3144
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewBitBakeProjectWizardAction.java
@@ -0,0 +1,48 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import org.eclipse.jface.action.IAction;
14import org.eclipse.jface.viewers.ISelection;
15import org.eclipse.jface.viewers.IStructuredSelection;
16import org.eclipse.jface.wizard.WizardDialog;
17import org.eclipse.ui.IWorkbenchWindow;
18import org.eclipse.ui.IWorkbenchWindowActionDelegate;
19
20import org.yocto.bc.ui.wizards.importProject.ImportYoctoProjectWizard;
21
22public class LaunchNewBitBakeProjectWizardAction implements IWorkbenchWindowActionDelegate {
23
24 private IWorkbenchWindow window;
25 private IStructuredSelection selection;
26
27 public void dispose() {
28 }
29
30 public void init(IWorkbenchWindow window) {
31 this.window = window;
32 }
33
34 public void run(IAction action) {
35 ImportYoctoProjectWizard wizard = new ImportYoctoProjectWizard();
36
37 wizard.init(window.getWorkbench(), selection);
38 WizardDialog wd = new WizardDialog(window.getShell(), wizard);
39 wd.create();
40 wd.open();
41 }
42
43 public void selectionChanged(IAction action, ISelection selection) {
44 if (selection instanceof IStructuredSelection) {
45 this.selection = (IStructuredSelection) selection;
46 }
47 }
48} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewRecipeWizardAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewRecipeWizardAction.java
new file mode 100644
index 0000000..d30d37b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchNewRecipeWizardAction.java
@@ -0,0 +1,48 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import org.eclipse.jface.action.IAction;
14import org.eclipse.jface.viewers.ISelection;
15import org.eclipse.jface.viewers.IStructuredSelection;
16import org.eclipse.jface.wizard.WizardDialog;
17import org.eclipse.ui.IWorkbenchWindow;
18import org.eclipse.ui.IWorkbenchWindowActionDelegate;
19
20import org.yocto.bc.ui.wizards.NewBitBakeFileRecipeWizard;
21
22public class LaunchNewRecipeWizardAction implements IWorkbenchWindowActionDelegate {
23
24 private IWorkbenchWindow window;
25 private IStructuredSelection selection;
26
27 public void dispose() {
28 }
29
30 public void init(IWorkbenchWindow window) {
31 this.window = window;
32 }
33
34 public void run(IAction action) {
35 NewBitBakeFileRecipeWizard wizard = new NewBitBakeFileRecipeWizard();
36
37 wizard.init(window.getWorkbench(), selection);
38 WizardDialog wd = new WizardDialog(window.getShell(), wizard);
39 wd.create();
40 wd.open();
41 }
42
43 public void selectionChanged(IAction action, ISelection selection) {
44 if (selection instanceof IStructuredSelection) {
45 this.selection = (IStructuredSelection) selection;
46 }
47 }
48} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchVariableWizardAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchVariableWizardAction.java
new file mode 100644
index 0000000..eaf716e
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/actions/LaunchVariableWizardAction.java
@@ -0,0 +1,78 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.actions;
12
13import java.io.IOException;
14import java.util.Map;
15
16import org.eclipse.core.resources.IProject;
17import org.eclipse.core.resources.IResource;
18import org.eclipse.core.runtime.CoreException;
19import org.eclipse.jface.action.IAction;
20import org.eclipse.jface.viewers.ISelection;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.jface.wizard.WizardDialog;
23import org.eclipse.ui.IWorkbenchWindow;
24import org.eclipse.ui.IWorkbenchWindowActionDelegate;
25
26import org.yocto.bc.ui.Activator;
27import org.yocto.bc.ui.builder.BitbakeCommanderNature;
28import org.yocto.bc.ui.wizards.variable.VariableWizard;
29
30/**
31 * Action to launch the Variable Wizard.
32 * @author kgilmer
33 *
34 */
35public class LaunchVariableWizardAction implements IWorkbenchWindowActionDelegate {
36
37 private IWorkbenchWindow window;
38 private Map session;
39
40 public void dispose() {
41 }
42
43 public void init(IWorkbenchWindow window) {
44 this.window = window;
45 }
46
47 public void run(IAction action) {
48 VariableWizard wizard = new VariableWizard(session);
49
50 WizardDialog wd = new WizardDialog(window.getShell(), wizard);
51 wd.create();
52 wd.open();
53 }
54
55 public void selectionChanged(IAction action, ISelection selection) {
56 session = null;
57
58 if (selection instanceof IStructuredSelection) {
59 Object element = ((IStructuredSelection)selection).getFirstElement();
60
61 if (element instanceof IResource) {
62 IProject p = ((IResource)element).getProject();
63
64 try {
65 if (p.isOpen() && p.hasNature(BitbakeCommanderNature.NATURE_ID)) {
66 session = Activator.getBBSession(((IResource)element).getProject().getLocationURI().getPath());
67 }
68 } catch (IOException e) {
69 e.printStackTrace();
70 } catch (CoreException e) {
71 e.printStackTrace();
72 }
73 }
74 }
75
76 action.setEnabled(session != null);
77 }
78} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeBuilder.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeBuilder.java
new file mode 100644
index 0000000..3705d9b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeBuilder.java
@@ -0,0 +1,177 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.builder;
12
13import java.util.Map;
14
15import javax.xml.parsers.ParserConfigurationException;
16import javax.xml.parsers.SAXParser;
17import javax.xml.parsers.SAXParserFactory;
18
19import org.eclipse.core.resources.IFile;
20import org.eclipse.core.resources.IMarker;
21import org.eclipse.core.resources.IProject;
22import org.eclipse.core.resources.IResource;
23import org.eclipse.core.resources.IResourceDelta;
24import org.eclipse.core.resources.IResourceDeltaVisitor;
25import org.eclipse.core.resources.IncrementalProjectBuilder;
26import org.eclipse.core.runtime.CoreException;
27import org.eclipse.core.runtime.IProgressMonitor;
28import org.xml.sax.SAXException;
29
30public class BitbakeBuilder extends IncrementalProjectBuilder {
31
32 class SampleDeltaVisitor implements IResourceDeltaVisitor {
33 /*
34 * (non-Javadoc)
35 *
36 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
37 */
38 public boolean visit(IResourceDelta delta) throws CoreException {
39 IResource resource = delta.getResource();
40 switch (delta.getKind()) {
41 case IResourceDelta.ADDED:
42 // handle added resource
43 //checkXML(resource);
44 break;
45 case IResourceDelta.REMOVED:
46 // handle removed resource
47 break;
48 case IResourceDelta.CHANGED:
49 // handle changed resource
50 //checkXML(resource);
51 break;
52 }
53 //return true to continue visiting children.
54 return true;
55 }
56 }
57/*
58 class SampleResourceVisitor implements IResourceVisitor {
59 public boolean visit(IResource resource) {
60
61 return true;
62 }
63 }
64*/
65/* class XMLErrorHandler extends DefaultHandler {
66
67 private IFile file;
68
69 public XMLErrorHandler(IFile file) {
70 this.file = file;
71 }
72
73 private void addMarker(SAXParseException e, int severity) {
74 BitbakeBuilder.this.addMarker(file, e.getMessage(), e
75 .getLineNumber(), severity);
76 }
77
78 @Override
79 public void error(SAXParseException exception) throws SAXException {
80 addMarker(exception, IMarker.SEVERITY_ERROR);
81 }
82
83 @Override
84 public void fatalError(SAXParseException exception) throws SAXException {
85 addMarker(exception, IMarker.SEVERITY_ERROR);
86 }
87
88 @Override
89 public void warning(SAXParseException exception) throws SAXException {
90 addMarker(exception, IMarker.SEVERITY_WARNING);
91 }
92 }
93*/
94 public static final String BUILDER_ID = "org.yocto.bc.ui.builder.BitbakeBuilder";
95 public static final String HOB_BUILD_ID = "org.yocto.bc.ui.builder.HOB";
96
97 private static final String MARKER_TYPE = "org.yocto.bc.ui.xmlProblem";
98
99 private SAXParserFactory parserFactory;
100
101 private void addMarker(IFile file, String message, int lineNumber,
102 int severity) {
103 try {
104 IMarker marker = file.createMarker(MARKER_TYPE);
105 marker.setAttribute(IMarker.MESSAGE, message);
106 marker.setAttribute(IMarker.SEVERITY, severity);
107 if (lineNumber == -1) {
108 lineNumber = 1;
109 }
110 marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
111 } catch (CoreException e) {
112 }
113 }
114
115 /*
116 * (non-Javadoc)
117 *
118 * @see org.eclipse.core.internal.events.InternalBuilder#build(int,
119 * java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
120 */
121 @Override
122 protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
123 throws CoreException {
124 if (kind == FULL_BUILD) {
125 fullBuild(monitor);
126 } else {
127 IResourceDelta delta = getDelta(getProject());
128 if (delta == null) {
129 fullBuild(monitor);
130 } else {
131 incrementalBuild(delta, monitor);
132 }
133 }
134 return null;
135 }
136
137 /*void checkXML(IResource resource) {
138 if (resource instanceof IFile && resource.getName().endsWith(".xml")) {
139 IFile file = (IFile) resource;
140 deleteMarkers(file);
141 XMLErrorHandler reporter = new XMLErrorHandler(file);
142 try {
143 getParser().parse(file.getContents(), reporter);
144 } catch (Exception e1) {
145 }
146 }
147 }*/
148
149 private void deleteMarkers(IFile file) {
150 try {
151 file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO);
152 } catch (CoreException ce) {
153 }
154 }
155
156 protected void fullBuild(final IProgressMonitor monitor)
157 throws CoreException {
158 /*try {
159 getProject().accept(new SampleResourceVisitor());
160 } catch (CoreException e) {
161 }*/
162 }
163
164 private SAXParser getParser() throws ParserConfigurationException,
165 SAXException {
166 if (parserFactory == null) {
167 parserFactory = SAXParserFactory.newInstance();
168 }
169 return parserFactory.newSAXParser();
170 }
171
172 protected void incrementalBuild(IResourceDelta delta,
173 IProgressMonitor monitor) throws CoreException {
174 // the visitor does the work.
175 delta.accept(new SampleDeltaVisitor());
176 }
177}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeCommanderNature.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeCommanderNature.java
new file mode 100644
index 0000000..fe2a997
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/BitbakeCommanderNature.java
@@ -0,0 +1,118 @@
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 - extend to support HOB build
11 *******************************************************************************/
12package org.yocto.bc.ui.builder;
13
14import java.util.ArrayList;
15
16import org.eclipse.core.resources.ICommand;
17import org.eclipse.core.resources.IProject;
18import org.eclipse.core.resources.IProjectDescription;
19import org.eclipse.core.resources.IProjectNature;
20import org.eclipse.core.runtime.CoreException;
21import org.eclipse.debug.core.DebugPlugin;
22import org.eclipse.debug.core.ILaunchConfigurationType;
23import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
24import org.eclipse.debug.core.ILaunchManager;
25
26
27public class BitbakeCommanderNature implements IProjectNature {
28
29 /**
30 * ID of this project nature
31 */
32 public static final String NATURE_ID = "org.yocto.bc.ui.builder.BitbakeCommanderNature";
33 public static final String BUILD_DIR_KEY = "org.yocto.bc.ui.builder.BitbakeCommander.BuildDir";
34 private IProject project;
35
36 public static void launchHob(IProject project, String buildDir) {
37 try {
38 ILaunchManager lManager = DebugPlugin.getDefault().getLaunchManager();
39 ILaunchConfigurationType configType =
40 lManager.getLaunchConfigurationType("org.eclipse.ui.externaltools.ProgramLaunchConfigurationType");
41 ILaunchConfigurationWorkingCopy w_copy = configType.newInstance(null, "hob");
42 ArrayList<String> listValue = new ArrayList<String>();
43 listValue.add(new String("org.eclipse.ui.externaltools.launchGroup"));
44 w_copy.setAttribute("org.eclipse.debug.ui.favoriteGroups", listValue);
45 w_copy.setAttribute("org.eclipse.ui.externaltools.ATTR_LOCATION", "/usr/bin/xterm");
46
47 String init_script = project.getLocation().toString() + "/oe-init-build-env ";
48 String argument = "-e \"source " + init_script + buildDir + ";hob";// + ";bash\"";
49
50 w_copy.setAttribute("org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS", argument);
51 w_copy.launch(ILaunchManager.RUN_MODE, null);
52
53 } catch (CoreException e) {
54 System.out.println(e.getMessage());
55 }
56 }
57 /*
58 * (non-Javadoc)
59 *
60 * @see org.eclipse.core.resources.IProjectNature#configure()
61 */
62 public void configure() throws CoreException {
63 IProjectDescription desc = project.getDescription();
64 ICommand[] commands = desc.getBuildSpec();
65
66 for (int i = 0; i < commands.length; ++i) {
67 if (commands[i].getBuilderName().equals(BitbakeBuilder.BUILDER_ID)) {
68 return;
69 }
70 }
71
72 ICommand[] newCommands = new ICommand[commands.length + 1];
73 System.arraycopy(commands, 0, newCommands, 0, commands.length);
74 ICommand command = desc.newCommand();
75 command.setBuilderName(BitbakeBuilder.BUILDER_ID);
76 newCommands[newCommands.length - 1] = command;
77 desc.setBuildSpec(newCommands);
78 project.setDescription(desc, null);
79 }
80
81 /*
82 * (non-Javadoc)
83 *
84 * @see org.eclipse.core.resources.IProjectNature#deconfigure()
85 */
86 public void deconfigure() throws CoreException {
87 IProjectDescription description = getProject().getDescription();
88 ICommand[] commands = description.getBuildSpec();
89 for (int i = 0; i < commands.length; ++i) {
90 if (commands[i].getBuilderName().equals(BitbakeBuilder.BUILDER_ID)) {
91 ICommand[] newCommands = new ICommand[commands.length - 1];
92 System.arraycopy(commands, 0, newCommands, 0, i);
93 System.arraycopy(commands, i + 1, newCommands, i,
94 commands.length - i - 1);
95 description.setBuildSpec(newCommands);
96 return;
97 }
98 }
99 }
100
101 /*
102 * (non-Javadoc)
103 *
104 * @see org.eclipse.core.resources.IProjectNature#getProject()
105 */
106 public IProject getProject() {
107 return project;
108 }
109
110 /*
111 * (non-Javadoc)
112 *
113 * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
114 */
115 public void setProject(IProject project) {
116 this.project = project;
117 }
118}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/ToggleNatureAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/ToggleNatureAction.java
new file mode 100644
index 0000000..f25148d
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/builder/ToggleNatureAction.java
@@ -0,0 +1,106 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.builder;
12
13import java.util.Iterator;
14
15import org.eclipse.core.resources.IProject;
16import org.eclipse.core.resources.IProjectDescription;
17import org.eclipse.core.runtime.CoreException;
18import org.eclipse.core.runtime.IAdaptable;
19import org.eclipse.jface.action.IAction;
20import org.eclipse.jface.viewers.ISelection;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.ui.IObjectActionDelegate;
23import org.eclipse.ui.IWorkbenchPart;
24
25public class ToggleNatureAction implements IObjectActionDelegate {
26
27 private ISelection selection;
28
29 /*
30 * (non-Javadoc)
31 *
32 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
33 */
34 public void run(IAction action) {
35 if (selection instanceof IStructuredSelection) {
36 for (Iterator it = ((IStructuredSelection) selection).iterator(); it
37 .hasNext();) {
38 Object element = it.next();
39 IProject project = null;
40 if (element instanceof IProject) {
41 project = (IProject) element;
42 } else if (element instanceof IAdaptable) {
43 project = (IProject) ((IAdaptable) element)
44 .getAdapter(IProject.class);
45 }
46 if (project != null) {
47 toggleNature(project);
48 }
49 }
50 }
51 }
52
53 /*
54 * (non-Javadoc)
55 *
56 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
57 * org.eclipse.jface.viewers.ISelection)
58 */
59 public void selectionChanged(IAction action, ISelection selection) {
60 this.selection = selection;
61 }
62
63 /*
64 * (non-Javadoc)
65 *
66 * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction,
67 * org.eclipse.ui.IWorkbenchPart)
68 */
69 public void setActivePart(IAction action, IWorkbenchPart targetPart) {
70 }
71
72 /**
73 * Toggles sample nature on a project
74 *
75 * @param project
76 * to have sample nature added or removed
77 */
78 private void toggleNature(IProject project) {
79 try {
80 IProjectDescription description = project.getDescription();
81 String[] natures = description.getNatureIds();
82
83 for (int i = 0; i < natures.length; ++i) {
84 if (BitbakeCommanderNature.NATURE_ID.equals(natures[i])) {
85 // Remove the nature
86 String[] newNatures = new String[natures.length - 1];
87 System.arraycopy(natures, 0, newNatures, 0, i);
88 System.arraycopy(natures, i + 1, newNatures, i,
89 natures.length - i - 1);
90 description.setNatureIds(newNatures);
91 project.setDescription(description, null);
92 return;
93 }
94 }
95
96 // Add the nature
97 String[] newNatures = new String[natures.length + 1];
98 System.arraycopy(natures, 0, newNatures, 0, natures.length);
99 newNatures[natures.length] = BitbakeCommanderNature.NATURE_ID;
100 description.setNatureIds(newNatures);
101 project.setDescription(description, null);
102 } catch (CoreException e) {
103 }
104 }
105
106}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ProjectDecorator.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ProjectDecorator.java
new file mode 100644
index 0000000..5901ee1
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ProjectDecorator.java
@@ -0,0 +1,48 @@
1package org.yocto.bc.ui.decorators;
2
3import org.eclipse.core.resources.IProject;
4import org.eclipse.core.runtime.CoreException;
5import org.eclipse.jface.resource.ImageDescriptor;
6import org.eclipse.jface.viewers.IDecoration;
7import org.eclipse.jface.viewers.ILabelProviderListener;
8import org.eclipse.jface.viewers.ILightweightLabelDecorator;
9
10import org.yocto.bc.ui.Activator;
11import org.yocto.bc.ui.builder.BitbakeCommanderNature;
12
13public class ProjectDecorator implements ILightweightLabelDecorator {
14
15 private ImageDescriptor image;
16
17 public ProjectDecorator() {
18 image = Activator.getImageDescriptor("icons/oe_decorator.gif");
19 }
20
21
22 public void decorate(Object element, IDecoration decoration) {
23 IProject p = (IProject) element;
24
25 try {
26 if (p.isOpen() && p.hasNature(BitbakeCommanderNature.NATURE_ID)) {
27 decoration.addOverlay(image, IDecoration.TOP_RIGHT);
28 }
29 } catch (CoreException e) {
30 e.printStackTrace();
31 }
32 }
33
34 public void addListener(ILabelProviderListener arg0) {
35 }
36
37 public void dispose() {
38 }
39
40 public boolean isLabelProperty(Object arg0, String arg1) {
41 return false;
42 }
43
44
45 public void removeListener(ILabelProviderListener arg0) {
46 }
47
48}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ReadOnly.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ReadOnly.java
new file mode 100644
index 0000000..0bb3c20
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/decorators/ReadOnly.java
@@ -0,0 +1,107 @@
1/*******************************************************************************
2 * Copyright (c) 2006 IBM Corporation and others.
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 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.decorators;
12
13import java.net.URL;
14
15import org.eclipse.core.resources.IResource;
16import org.eclipse.core.resources.ResourceAttributes;
17import org.eclipse.core.runtime.Path;
18import org.eclipse.core.runtime.Platform;
19import org.eclipse.jface.resource.ImageDescriptor;
20import org.eclipse.jface.viewers.IDecoration;
21import org.eclipse.jface.viewers.ILabelProviderListener;
22import org.eclipse.jface.viewers.ILightweightLabelDecorator;
23
24/**
25 * An example showing how to control when an element is decorated. This example
26 * decorates only elements that are instances of IResource and whose attribute
27 * is 'Read-only'.
28 *
29 * @see ILightweightLabelDecorator
30 */
31public class ReadOnly implements ILightweightLabelDecorator {
32 /**
33 * String constants for the various icon placement options from the template
34 * wizard.
35 */
36 public static final String TOP_RIGHT = "TOP_RIGHT";
37
38 public static final String TOP_LEFT = "TOP_LEFT";
39
40 public static final String BOTTOM_RIGHT = "BOTTOM_RIGHT";
41
42 public static final String BOTTOM_LEFT = "BOTTOM_LEFT";
43
44 public static final String UNDERLAY = "UNDERLAY";
45
46 /** The integer value representing the placement options */
47 private int quadrant;
48
49 /** The icon image location in the project folder */
50 private String iconPath = "icons/read_only.gif"; //NON-NLS-1
51
52 /**
53 * The image description used in
54 * <code>addOverlay(ImageDescriptor, int)</code>
55 */
56 private ImageDescriptor descriptor;
57
58 /* (non-Javadoc)
59 * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration)
60 */
61 public void decorate(Object element, IDecoration decoration) {
62 /**
63 * Checks that the element is an IResource with the 'Read-only' attribute
64 * and adds the decorator based on the specified image description and the
65 * integer representation of the placement option.
66 */
67 IResource resource = (IResource) element;
68 ResourceAttributes attrs = resource.getResourceAttributes();
69 if(attrs!=null) {
70 if (attrs.isReadOnly()){
71 URL url = Platform.find(
72 Platform.getBundle("org.yocto.bc.ui"), new Path(iconPath)); //NON-NLS-1
73
74 if (url == null)
75 return;
76 descriptor = ImageDescriptor.createFromURL(url);
77 quadrant = IDecoration.TOP_RIGHT;
78 decoration.addOverlay(descriptor,quadrant);
79 }
80 }
81 }
82
83 /* (non-Javadoc)
84 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
85 */
86 public void addListener(ILabelProviderListener listener) {
87 }
88
89 /* (non-Javadoc)
90 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
91 */
92 public void dispose() {
93 }
94
95 /* (non-Javadoc)
96 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
97 */
98 public boolean isLabelProperty(Object element, String property) {
99 return false;
100 }
101
102 /* (non-Javadoc)
103 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
104 */
105 public void removeListener(ILabelProviderListener listener) {
106 }
107} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BBVariableTextHover.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BBVariableTextHover.java
new file mode 100644
index 0000000..9478423
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BBVariableTextHover.java
@@ -0,0 +1,118 @@
1/**
2 *
3 */
4package org.yocto.bc.ui.editors.bitbake;
5
6import java.io.File;
7import java.util.Map;
8
9import org.eclipse.core.runtime.IProgressMonitor;
10import org.eclipse.core.runtime.IStatus;
11import org.eclipse.core.runtime.Status;
12import org.eclipse.core.runtime.jobs.Job;
13import org.eclipse.jface.text.IRegion;
14import org.eclipse.jface.text.ITextHover;
15import org.eclipse.jface.text.ITextViewer;
16import org.eclipse.jface.text.Region;
17
18import org.yocto.bc.bitbake.BBRecipe;
19import org.yocto.bc.bitbake.BBSession;
20import org.yocto.bc.ui.Activator;
21
22/**
23 * Maps BB Variables in the editor to BBSession
24 * @author kgilmer
25 *
26 */
27class BBVariableTextHover implements ITextHover {
28 private final BBSession session;
29 private volatile Map envMap;
30
31 public BBVariableTextHover(BBSession session, String file) {
32 this.session = session;
33 envMap = session;
34 LoadRecipeJob loadRecipeJob = new LoadRecipeJob(getFilename(file), file);
35 loadRecipeJob.schedule();
36 }
37
38 private String getFilename(String file) {
39
40 String [] elems = file.split(File.separator);
41
42 return elems[elems.length - 1];
43 }
44
45 public IRegion getHoverRegion(ITextViewer tv, int off) {
46 return new Region(off, 0);
47 }
48
49 public String getHoverInfo(ITextViewer tv, IRegion r) {
50 try {
51 IRegion lineRegion = tv.getDocument().getLineInformationOfOffset(r.getOffset());
52
53 return getBBVariable(tv.getDocument().get(lineRegion.getOffset(), lineRegion.getLength()).toCharArray(), r.getOffset() - lineRegion.getOffset());
54 } catch (Exception e) {
55 return "";
56 }
57 }
58
59 private String getBBVariable(char[] line, int offset) {
60 // Find start of word.
61 int i = offset;
62
63 while (line[i] != ' ' && line[i] != '$' && i > 0) {
64 i--;
65 }
66
67 if (i < 0 || line[i] != '$') {
68 return ""; //this is not a BB variable.
69 }
70
71 // find end of word
72 int start = i;
73 i = offset;
74
75 while (line[i] != ' ' && line[i] != '}' && i <= line.length) {
76 i++;
77 }
78
79 if (line[i] != '}') {
80 return ""; //this bb variable didn't terminate as expected
81 }
82
83 String key = new String(line, start + 2, i - start - 2);
84 String val = (String) envMap.get(key);
85
86 if (val == null) {
87 val = "";
88 }
89
90 if (val.length() > 64) {
91 val = val.substring(0, 64) + '\n' + val.substring(65);
92 }
93
94 return val;
95 }
96
97 private class LoadRecipeJob extends Job {
98 private final String filePath;
99
100 public LoadRecipeJob(String name, String filePath) {
101 super("Extracting BitBake environment for " + name);
102 this.filePath = filePath;
103 }
104
105 @Override
106 protected IStatus run(IProgressMonitor mon) {
107 try {
108 BBRecipe recipe = Activator.getBBRecipe(session, filePath);
109 recipe.initialize();
110 envMap = recipe;
111 } catch (Exception e) {
112 return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Unable to load session for " + filePath, e);
113 }
114
115 return Status.OK_STATUS;
116 }
117 }
118} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeDocumentProvider.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeDocumentProvider.java
new file mode 100644
index 0000000..4713bc3
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeDocumentProvider.java
@@ -0,0 +1,62 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import org.eclipse.jface.text.IDocument;
14import org.eclipse.jface.text.IDocumentExtension3;
15import org.eclipse.jface.text.IDocumentPartitioner;
16import org.eclipse.jface.text.rules.FastPartitioner;
17import org.eclipse.jface.text.rules.IPredicateRule;
18import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
19import org.eclipse.jface.text.rules.SingleLineRule;
20import org.eclipse.jface.text.rules.Token;
21import org.eclipse.ui.editors.text.FileDocumentProvider;
22
23/**
24 * Document provider for BB recipe.
25 * @author kgilmer
26 *
27 */
28public class BitBakeDocumentProvider extends FileDocumentProvider {
29 /**
30 * The recipe partitioning. It contains two partition types: {@link #RECIPE_CODE} and
31 * {@link #RECIPE_COMMENT}.
32 */
33 public static final String RECIPE_PARTITIONING= "org.recipeeditor.recipepartitioning"; //$NON-NLS-1$
34
35 public static final String RECIPE_CODE= IDocument.DEFAULT_CONTENT_TYPE;
36 public static final String RECIPE_COMMENT= "RECIPE_COMMENT"; //$NON-NLS-1$
37
38 private static final String[] CONTENT_TYPES= {
39 RECIPE_CODE,
40 RECIPE_COMMENT
41 };
42
43 private IDocumentPartitioner createRecipePartitioner() {
44 IPredicateRule[] rules= { new SingleLineRule("#", null, new Token(RECIPE_COMMENT), (char) 0, true, false) }; //$NON-NLS-1$
45
46 RuleBasedPartitionScanner scanner= new RuleBasedPartitionScanner();
47 scanner.setPredicateRules(rules);
48
49 return new FastPartitioner(scanner, CONTENT_TYPES);
50 }
51
52 @Override
53 protected void setupDocument(Object element,IDocument document) {
54 if (document instanceof IDocumentExtension3) {
55 IDocumentExtension3 ext= (IDocumentExtension3) document;
56 IDocumentPartitioner partitioner= createRecipePartitioner();
57 ext.setDocumentPartitioner(RECIPE_PARTITIONING, partitioner);
58 partitioner.connect(document);
59 }
60 }
61
62}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeFileEditor.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeFileEditor.java
new file mode 100644
index 0000000..b33f030
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeFileEditor.java
@@ -0,0 +1,75 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import java.io.IOException;
14import java.util.ResourceBundle;
15
16import org.eclipse.core.resources.IFile;
17import org.eclipse.core.resources.IProject;
18import org.eclipse.core.runtime.Status;
19import org.eclipse.ui.IEditorInput;
20import org.eclipse.ui.IEditorSite;
21import org.eclipse.ui.PartInitException;
22import org.eclipse.ui.part.FileEditorInput;
23import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
24import org.eclipse.ui.texteditor.ContentAssistAction;
25import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
26
27import org.yocto.bc.ui.Activator;
28
29/**
30 * Editor for BB Recipe
31 * @author kgilmer
32 *
33 */
34public class BitBakeFileEditor extends AbstractDecoratedTextEditor {
35
36 public static final String EDITOR_ID = "org.yocto.bc.ui.editors.BitBakeFileEditor";
37 static final String CONTENT_ASSIST= "ContentAssist";
38 private BitBakeSourceViewerConfiguration viewerConfiguration;
39 private IFile targetFile;
40
41 public BitBakeFileEditor() {
42 super();
43 viewerConfiguration = new BitBakeSourceViewerConfiguration(getSharedColors(), getPreferenceStore());
44 setSourceViewerConfiguration(viewerConfiguration);
45 setDocumentProvider(new BitBakeDocumentProvider());
46 }
47
48 @Override
49 protected void createActions() {
50 super.createActions();
51
52 ResourceBundle bundle= RecipeEditorMessages.getBundle();
53 ContentAssistAction action= new ContentAssistAction(bundle, "contentAssist.", this); //$NON-NLS-1$
54 action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
55 setAction(CONTENT_ASSIST, action);
56 }
57
58 @Override
59 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
60
61 if (input instanceof FileEditorInput) {
62 IProject p = ((FileEditorInput)input).getFile().getProject();
63 targetFile = ((FileEditorInput)input).getFile();
64 viewerConfiguration.setTargetFile(targetFile);
65
66 try {
67 viewerConfiguration.setBBSession(Activator.getBBSession(p.getLocationURI().getPath()));
68 } catch (IOException e) {
69 e.printStackTrace();
70 throw new PartInitException(Status.CANCEL_STATUS);
71 }
72 }
73 super.init(site, input);
74 }
75} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java
new file mode 100644
index 0000000..56cd014
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/BitBakeSourceViewerConfiguration.java
@@ -0,0 +1,195 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import org.eclipse.core.resources.IFile;
14import org.eclipse.jface.preference.IPreferenceStore;
15import org.eclipse.jface.text.ITextHover;
16import org.eclipse.jface.text.TextAttribute;
17import org.eclipse.jface.text.contentassist.ContentAssistant;
18import org.eclipse.jface.text.contentassist.IContentAssistant;
19import org.eclipse.jface.text.presentation.IPresentationReconciler;
20import org.eclipse.jface.text.presentation.PresentationReconciler;
21import org.eclipse.jface.text.reconciler.IReconciler;
22import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
23import org.eclipse.jface.text.rules.IRule;
24import org.eclipse.jface.text.rules.IToken;
25import org.eclipse.jface.text.rules.IWordDetector;
26import org.eclipse.jface.text.rules.RuleBasedScanner;
27import org.eclipse.jface.text.rules.SingleLineRule;
28import org.eclipse.jface.text.rules.Token;
29import org.eclipse.jface.text.rules.WordRule;
30import org.eclipse.jface.text.source.ISharedTextColors;
31import org.eclipse.jface.text.source.ISourceViewer;
32import org.eclipse.swt.SWT;
33import org.eclipse.swt.graphics.Color;
34import org.eclipse.swt.graphics.RGB;
35import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
36
37import org.yocto.bc.bitbake.BBLanguageHelper;
38import org.yocto.bc.bitbake.BBSession;
39
40public class BitBakeSourceViewerConfiguration extends TextSourceViewerConfiguration {
41
42 private static final class WordDetector implements IWordDetector {
43 public boolean isWordPart(char c) {
44 return !Character.isWhitespace(c);
45 }
46
47 public boolean isWordStart(char c) {
48 return !Character.isWhitespace(c);
49 }
50 }
51
52 private final ISharedTextColors fSharedColors;
53 private BBSession session;
54 private IFile targetFile;
55 private BBVariableTextHover textHover = null;
56
57 public BitBakeSourceViewerConfiguration(ISharedTextColors sharedColors, IPreferenceStore store) {
58 super(store);
59 fSharedColors = sharedColors;
60 }
61
62 protected void setTargetFile(IFile targetFile) {
63 this.targetFile = targetFile;
64 }
65
66 public ITextHover getTextHover(ISourceViewer sv, String contentType) {
67 //only .bb file support Text Hover.
68 if (textHover == null && targetFile.getFileExtension().equals(BBLanguageHelper.BITBAKE_RECIPE_FILE_EXTENSION)) {
69 textHover = new BBVariableTextHover(session, targetFile.getLocationURI().getPath());
70 }
71
72 return textHover;
73 }
74
75 private void addDamagerRepairer(PresentationReconciler reconciler, RuleBasedScanner commentScanner, String contentType) {
76 DefaultDamagerRepairer commentDamagerRepairer = new DefaultDamagerRepairer(commentScanner);
77 reconciler.setDamager(commentDamagerRepairer, contentType);
78 reconciler.setRepairer(commentDamagerRepairer, contentType);
79 }
80
81 private RuleBasedScanner createCommentScanner() {
82 Color green = fSharedColors.getColor(new RGB(16, 96, 16));
83 RuleBasedScanner commentScanner = new RuleBasedScanner();
84 commentScanner.setDefaultReturnToken(new Token(new TextAttribute(green, null, SWT.ITALIC)));
85 return commentScanner;
86 }
87
88 private IRule createCustomFunctionRule() {
89 Color blue = fSharedColors.getColor(new RGB(130, 0, 0));
90 IRule rule = new CustomFunctionRule(new Token(new TextAttribute(blue, null, SWT.BOLD)));
91
92 return rule;
93 }
94
95 private SingleLineRule createFunctionNameRule() {
96 Color red = fSharedColors.getColor(new RGB(150, 0, 96));
97 SingleLineRule stepRule = new SingleLineRule("do_", ")", new Token(new TextAttribute(red, null, SWT.BOLD))); //$NON-NLS-1$ //$NON-NLS-2$
98 stepRule.setColumnConstraint(0);
99 return stepRule;
100 }
101
102 private SingleLineRule createInlineVariableRule() {
103 Color blue = fSharedColors.getColor(new RGB(50, 50, 100));
104 SingleLineRule stepRule = new SingleLineRule("${", "}", new Token(new TextAttribute(blue, null, SWT.BOLD))); //$NON-NLS-1$ //$NON-NLS-2$
105 return stepRule;
106 }
107
108 private WordRule createKeywordRule() {
109 WordRule keywordRule = new WordRule(new WordDetector());
110 IToken token = new Token(new TextAttribute(fSharedColors.getColor(new RGB(96, 96, 0)), null, SWT.NONE));
111
112 for (int i = 0; i < BBLanguageHelper.BITBAKE_KEYWORDS.length; ++i) {
113
114 keywordRule.addWord(BBLanguageHelper.BITBAKE_KEYWORDS[i], token);
115 keywordRule.setColumnConstraint(0);
116 }
117
118 return keywordRule;
119 }
120
121 private RuleBasedScanner createRecipeScanner() {
122 RuleBasedScanner recipeScanner = new RuleBasedScanner();
123
124 IRule[] rules = { createKeywordRule(), createShellKeywordRule(), createStringLiteralRule(), createVariableRule(), createFunctionNameRule(), createCustomFunctionRule(),
125 createInlineVariableRule() };
126 recipeScanner.setRules(rules);
127 return recipeScanner;
128 }
129
130 private WordRule createShellKeywordRule() {
131 WordRule keywordRule = new WordRule(new WordDetector());
132 IToken token = new Token(new TextAttribute(fSharedColors.getColor(new RGB(0, 64, 92)), null, SWT.NONE));
133
134 for (int i = 0; i < BBLanguageHelper.SHELL_KEYWORDS.length; ++i) {
135 keywordRule.addWord(BBLanguageHelper.SHELL_KEYWORDS[i], token);
136 }
137
138 return keywordRule;
139 }
140
141 private SingleLineRule createStringLiteralRule() {
142 Color red = fSharedColors.getColor(new RGB(50, 50, 100));
143 SingleLineRule rule = new SingleLineRule("\"", "\"", new Token(new TextAttribute(red, null, SWT.NONE)), '\\');
144
145 return rule;
146 }
147
148 private IRule createVariableRule() {
149 Color blue = fSharedColors.getColor(new RGB(0, 0, 200));
150 IRule rule = new VariableRule(new Token(new TextAttribute(blue, null, SWT.NONE)));
151
152 return rule;
153 }
154
155 @Override
156 public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
157 return new String[] { BitBakeDocumentProvider.RECIPE_CODE, BitBakeDocumentProvider.RECIPE_COMMENT };
158 }
159
160 @Override
161 public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
162 return BitBakeDocumentProvider.RECIPE_PARTITIONING;
163 }
164
165 @Override
166 public IContentAssistant getContentAssistant(final ISourceViewer sourceViewer) {
167 ContentAssistant assistant = new ContentAssistant();
168 assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
169
170 // assistant.setContentAssistProcessor(new HippieProposalProcessor(),
171 // BitBakeDocumentProvider.RECIPE_COMMENT);
172 assistant.setContentAssistProcessor(new RecipeCompletionProcessor(), BitBakeDocumentProvider.RECIPE_CODE);
173
174 return assistant;
175 }
176
177 public IReconciler getReconciler(ISourceViewer sourceViewer) {
178 return null;
179 }
180
181 @Override
182 public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
183 PresentationReconciler reconciler = new PresentationReconciler();
184 reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
185
186 addDamagerRepairer(reconciler, createCommentScanner(), BitBakeDocumentProvider.RECIPE_COMMENT);
187 addDamagerRepairer(reconciler, createRecipeScanner(), BitBakeDocumentProvider.RECIPE_CODE);
188
189 return reconciler;
190 }
191
192 public void setBBSession(BBSession session) {
193 this.session = session;
194 }
195}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/CustomFunctionRule.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/CustomFunctionRule.java
new file mode 100644
index 0000000..223a25d
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/CustomFunctionRule.java
@@ -0,0 +1,94 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import org.eclipse.jface.text.rules.ICharacterScanner;
14import org.eclipse.jface.text.rules.IRule;
15import org.eclipse.jface.text.rules.IToken;
16import org.eclipse.jface.text.rules.Token;
17
18/**
19 * Rule for def_ BB Recipe functions
20 * @author kgilmer
21 *
22 */
23final class CustomFunctionRule implements IRule {
24
25 /** Token to return for this rule */
26 private final IToken fToken;
27
28 /**
29 * Creates a new operator rule.
30 *
31 * @param token
32 * Token to use for this rule
33 */
34 public CustomFunctionRule(IToken token) {
35 fToken = token;
36 }
37
38 public IToken evaluate(ICharacterScanner scanner) {
39 if (scanner.getColumn() > 0) {
40 return Token.UNDEFINED;
41 }
42
43 int i = scanner.read();
44 int c = 1;
45
46 if (!Character.isLetter(i) && i != 10) {
47 scanner.unread();
48 return Token.UNDEFINED;
49 }
50
51 if (i == 'd' && scanAhead(scanner, "o_".toCharArray())) {
52 scanner.unread();
53 return Token.UNDEFINED;
54 }
55
56 while (i != ICharacterScanner.EOF && i != 10) {
57 i = scanner.read();
58 c++;
59
60 if (i == '(') {
61 readUntil(scanner, ')');
62
63 return fToken;
64 }
65 }
66
67 for (int t = 0; t < c; t++) {
68 scanner.unread();
69 }
70
71 return Token.UNDEFINED;
72 }
73
74 private void readUntil(ICharacterScanner scanner, int c) {
75 int i;
76 do {
77 i = scanner.read();
78 } while (! (i == ICharacterScanner.EOF) && ! (i == c));
79 }
80
81 private boolean scanAhead(ICharacterScanner scanner, char [] chars) {
82 boolean v = true;
83 for (int i = 0; i < chars.length; ++i) {
84 if (! (scanner.read() == chars[i])) {
85 v = false;
86 for (int j = 0; j < i; ++j) {
87 scanner.unread();
88 }
89 break;
90 }
91 }
92 return v;
93 }
94} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeCompletionProcessor.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeCompletionProcessor.java
new file mode 100644
index 0000000..034187a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeCompletionProcessor.java
@@ -0,0 +1,127 @@
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 * Lianhao Lu (Intel) - remove compile warnings
11 *******************************************************************************/
12package org.yocto.bc.ui.editors.bitbake;
13
14import java.util.ArrayList;
15import java.util.Arrays;
16import java.util.Iterator;
17import java.util.List;
18import java.util.Map;
19
20import org.eclipse.jface.text.IDocument;
21import org.eclipse.jface.text.ITextViewer;
22import org.eclipse.jface.text.Region;
23import org.eclipse.jface.text.contentassist.ICompletionProposal;
24import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
25import org.eclipse.jface.text.contentassist.IContextInformation;
26import org.eclipse.jface.text.contentassist.IContextInformationValidator;
27import org.eclipse.jface.text.templates.DocumentTemplateContext;
28import org.eclipse.jface.text.templates.Template;
29import org.eclipse.jface.text.templates.TemplateContext;
30import org.eclipse.jface.text.templates.TemplateContextType;
31import org.eclipse.jface.text.templates.TemplateProposal;
32import org.eclipse.swt.graphics.Image;
33import org.eclipse.ui.ide.IDE.SharedImages;
34import org.eclipse.ui.PlatformUI;
35
36import org.yocto.bc.bitbake.BBLanguageHelper;
37import org.yocto.bc.ui.Activator;
38
39class RecipeCompletionProcessor implements IContentAssistProcessor {
40
41 private static final String CONTEXT_ID= "bitbake_variables"; //$NON-NLS-1$
42 private final TemplateContextType fContextType= new TemplateContextType(CONTEXT_ID, "Common BitBake Variables"); //$NON-NLS-1$
43 //private final TemplateContextType fKeywordContextType= new TemplateContextType("bitbake_keywords", "BitBake Keywords"); //$NON-NLS-1$
44 private final TemplateContextType fFunctionContextType = new TemplateContextType("bitbake_functions", "BitBake Functions");
45
46 RecipeCompletionProcessor() {
47 }
48
49 public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
50 IDocument document= viewer.getDocument();
51 Region region= new Region(offset, 0);
52
53 TemplateContext templateContext= new DocumentTemplateContext(fContextType, document, offset, 0);
54 //TemplateContext keywordContext = new DocumentTemplateContext(fKeywordContextType, document, offset, 0);
55 TemplateContext functionContext = new DocumentTemplateContext(fFunctionContextType, document, offset, 0);
56
57 List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
58
59 getVariableTemplateProposals(templateContext, region, proposals);
60 // getKeywordTemplateProposals(keywordContext, region, proposals);
61 getAddTaskTemplateProposals(templateContext, region, proposals);
62 getFunctionTemplateProposals(functionContext, region, proposals);
63
64 return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]);
65 }
66
67 public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
68 return null;
69 }
70
71 private Template generateVariableTemplate(String name, String description) {
72
73 return new Template(name, description, CONTEXT_ID, name + " = \"${" + name.toLowerCase() + "}\"", false);
74 }
75
76 private void getAddTaskTemplateProposals(TemplateContext templateContext, Region region, List<ICompletionProposal> p) {
77 p.add(new TemplateProposal(new Template("addtask", "addtask statement", CONTEXT_ID, "addtask ${task_name} after ${do_previous_task} before ${do_next_task}", false),templateContext, region, PlatformUI.getWorkbench().getSharedImages().getImage(SharedImages.IMG_OBJS_BKMRK_TSK)));
78 }
79
80
81 public char[] getCompletionProposalAutoActivationCharacters() {
82 return null;
83 }
84
85 public char[] getContextInformationAutoActivationCharacters() {
86 return null;
87 }
88
89 public IContextInformationValidator getContextInformationValidator() {
90 return null;
91 }
92
93 public String getErrorMessage() {
94 return null;
95 }
96
97 private void getFunctionTemplateProposals(TemplateContext templateContext, Region region, List<ICompletionProposal> p) {
98 String [] keywords = BBLanguageHelper.BITBAKE_STANDARD_FUNCTIONS;
99 Image img = Activator.getDefault().getImageRegistry().get(Activator.IMAGE_FUNCTION);
100 Arrays.sort(keywords);
101
102 for (int i = 0; i < keywords.length; ++i) {
103 p.add(new TemplateProposal(new Template(keywords[i], keywords[i] + " function", CONTEXT_ID, "do_" + keywords[i] + "() {\n\n}", false), templateContext, region, img));
104 }
105 }
106 /*
107 private void getKeywordTemplateProposals(TemplateContext templateContext, Region region, List<TemplateProposal> p) {
108 String [] keywords = BBLanguageHelper.BITBAKE_KEYWORDS;
109
110 Arrays.sort(keywords);
111
112 for (int i = 0; i < keywords.length; ++i) {
113 p.add(new TemplateProposal(new Template(keywords[i], keywords[i] + " keyword", CONTEXT_ID, keywords[i] + " ", false),templateContext, region, null));
114 }
115 }
116 */
117
118 private void getVariableTemplateProposals(TemplateContext templateContext, Region region, List<ICompletionProposal> p) {
119 Map<String, String> n = BBLanguageHelper.getCommonBitbakeVariables();
120 Image img = Activator.getDefault().getImageRegistry().get(Activator.IMAGE_VARIABLE);
121 for (Iterator<String> i = n.keySet().iterator(); i.hasNext();) {
122 String name = (String) i.next();
123 String description = (String) n.get(name);
124 p.add(new TemplateProposal(generateVariableTemplate(name, description), templateContext, region, img));
125 }
126 }
127} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorActionContributor.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorActionContributor.java
new file mode 100644
index 0000000..f27951b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorActionContributor.java
@@ -0,0 +1,47 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import org.eclipse.jface.action.IMenuManager;
14import org.eclipse.ui.IEditorPart;
15import org.eclipse.ui.IWorkbenchActionConstants;
16import org.eclipse.ui.editors.text.TextEditorActionContributor;
17import org.eclipse.ui.texteditor.ITextEditor;
18import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
19import org.eclipse.ui.texteditor.RetargetTextEditorAction;
20
21public class RecipeEditorActionContributor extends TextEditorActionContributor {
22
23 private RetargetTextEditorAction fContentAssist;
24
25 public RecipeEditorActionContributor() {
26 fContentAssist= new RetargetTextEditorAction(RecipeEditorMessages.getBundle(), "contentAssist."); //$NON-NLS-1$
27 fContentAssist.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
28 }
29
30 @Override
31 public void contributeToMenu(IMenuManager menu) {
32 super.contributeToMenu(menu);
33
34 IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
35 if (editMenu != null) {
36 editMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fContentAssist);
37 }
38 }
39
40 @Override
41 public void setActiveEditor(IEditorPart part) {
42 super.setActiveEditor(part);
43 if (part instanceof ITextEditor) {
44 fContentAssist.setAction(getAction((ITextEditor) part, BitBakeFileEditor.CONTENT_ASSIST));
45 }
46 }
47}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.java
new file mode 100644
index 0000000..020a25a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.java
@@ -0,0 +1,21 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import java.util.ResourceBundle;
14
15public class RecipeEditorMessages {
16
17 public static ResourceBundle getBundle() {
18 return ResourceBundle.getBundle(RecipeEditorMessages.class.getName());
19 }
20
21}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.properties b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.properties
new file mode 100644
index 0000000..76c670b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/RecipeEditorMessages.properties
@@ -0,0 +1,14 @@
1#########################################################
2# Copyright (c) 2006 IBM Corporation and others.
3# All rights reserved. This program and the accompanying materials
4# are made available under the terms of the Common Public License v1.0
5# which accompanies this distribution, and is available at
6# http://www.eclipse.org/legal/cpl-v10.html
7#
8# Contributors:
9# IBM Corporation - initial API and implementation
10##########################################################
11contentAssist.label=Content Assist
12contentAssist.tooltip=Content Assist
13contentAssist.image=
14contentAssist.description= Invokes content assist \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/VariableRule.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/VariableRule.java
new file mode 100644
index 0000000..750705a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/editors/bitbake/VariableRule.java
@@ -0,0 +1,69 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.editors.bitbake;
12
13import org.eclipse.jface.text.rules.ICharacterScanner;
14import org.eclipse.jface.text.rules.IRule;
15import org.eclipse.jface.text.rules.IToken;
16import org.eclipse.jface.text.rules.Token;
17
18final class VariableRule implements IRule {
19
20 /** Token to return for this rule */
21 private final IToken fToken;
22
23 /**
24 * Creates a new operator rule.
25 *
26 * @param token
27 * Token to use for this rule
28 */
29 public VariableRule(IToken token) {
30 fToken = token;
31 }
32
33 public IToken evaluate(ICharacterScanner scanner) {
34 if (scanner.getColumn() > 0) {
35 return Token.UNDEFINED;
36 }
37
38 int i = scanner.read();
39 int c = 1;
40
41 if (!Character.isLetter(i) && i != 10) {
42 scanner.unread();
43 return Token.UNDEFINED;
44 }
45
46 int p = i;
47
48 while (i != ICharacterScanner.EOF && i != 10) {
49 p = i;
50 i = scanner.read();
51 c++;
52
53 if (i == '=') {
54 scanner.unread();
55
56 if (p == '?' || p == '+') {
57 scanner.unread();
58 }
59 return fToken;
60 }
61 }
62
63 for (int t = 0; t < c; t++) {
64 scanner.unread();
65 }
66
67 return Token.UNDEFINED;
68 }
69} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Messages.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Messages.java
new file mode 100644
index 0000000..0a82fdd
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Messages.java
@@ -0,0 +1,48 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.filesystem;
12
13import org.eclipse.osgi.util.NLS;
14
15/**
16 * Provides translatable messages for the file system bundle
17 */
18public class Messages extends NLS {
19 private static final String BUNDLE_NAME = "org.eclipse.core.internal.filesystem.messages"; //$NON-NLS-1$
20
21 public static String copying;
22 public static String couldnotDelete;
23 public static String couldnotDeleteReadOnly;
24 public static String couldNotLoadLibrary;
25 public static String couldNotMove;
26 public static String couldNotRead;
27 public static String couldNotWrite;
28 public static String deleteProblem;
29 public static String deleting;
30 public static String failedCreateWrongType;
31 public static String failedMove;
32 public static String failedReadDuringWrite;
33 public static String fileExists;
34 public static String fileNotFound;
35 public static String moving;
36 public static String noFileSystem;
37 public static String noImplDelete;
38 public static String noImplWrite;
39 public static String noScheme;
40 public static String notAFile;
41 public static String readOnlyParent;
42
43 static {
44 // initialize resource bundles
45 NLS.initializeMessages(BUNDLE_NAME, Messages.class);
46 }
47
48}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFile.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFile.java
new file mode 100644
index 0000000..85794f1
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFile.java
@@ -0,0 +1,515 @@
1/*******************************************************************************
2 * Copyright (c) 2005, 2006 IBM Corporation and others.
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 * IBM Corporation - initial API and implementation
10 * Ken Gilmer - adaptation from internal class.
11 *******************************************************************************/
12package org.yocto.bc.ui.filesystem;
13
14import java.io.File;
15import java.io.FileInputStream;
16import java.io.FileNotFoundException;
17import java.io.FileOutputStream;
18import java.io.IOException;
19import java.io.InputStream;
20import java.io.OutputStream;
21import java.net.URI;
22import java.util.List;
23
24import org.eclipse.core.filesystem.EFS;
25import org.eclipse.core.filesystem.IFileInfo;
26import org.eclipse.core.filesystem.IFileStore;
27import org.eclipse.core.filesystem.IFileSystem;
28import org.eclipse.core.filesystem.URIUtil;
29import org.eclipse.core.filesystem.provider.FileInfo;
30import org.eclipse.core.filesystem.provider.FileStore;
31import org.eclipse.core.runtime.CoreException;
32import org.eclipse.core.runtime.IPath;
33import org.eclipse.core.runtime.IProgressMonitor;
34import org.eclipse.core.runtime.IStatus;
35import org.eclipse.core.runtime.MultiStatus;
36import org.eclipse.core.runtime.NullProgressMonitor;
37import org.eclipse.core.runtime.Status;
38import org.eclipse.osgi.util.NLS;
39import org.yocto.bc.bitbake.BBSession;
40import org.yocto.bc.bitbake.ProjectInfoHelper;
41import org.yocto.bc.bitbake.ShellSession;
42
43/**
44 * File system implementation based on storage of files in the local
45 * operating system's file system.
46 */
47public class OEFile extends FileStore {
48 private static int attributes(File aFile) {
49 if (!aFile.exists() || aFile.canWrite())
50 return EFS.NONE;
51 return EFS.ATTRIBUTE_READ_ONLY;
52 }
53
54 /**
55 * The java.io.File that this store represents.
56 */
57 protected final File file;
58 private List ignorePaths;
59
60 /**
61 * The absolute file system path of the file represented by this store.
62 */
63 protected final String filePath;
64
65 private final String root;
66
67 /**
68 * Creates a new local file.
69 *
70 * @param file The file this local file represents
71 * @param root
72 */
73 public OEFile(File file, List ignorePaths, String root) {
74 this.file = file;
75 this.ignorePaths = ignorePaths;
76 this.root = root;
77 this.filePath = file.getAbsolutePath();
78 }
79
80 /**
81 * This method is called after a failure to modify a file or directory.
82 * Check to see if the parent is read-only and if so then
83 * throw an exception with a more specific message and error code.
84 *
85 * @param target The file that we failed to modify
86 * @param exception The low level exception that occurred, or <code>null</code>
87 * @throws CoreException A more specific exception if the parent is read-only
88 */
89 private void checkReadOnlyParent(File target, Throwable exception) throws CoreException {
90 File parent = target.getParentFile();
91 if (parent != null && (attributes(parent) & EFS.ATTRIBUTE_READ_ONLY) != 0) {
92 String message = NLS.bind(Messages.readOnlyParent, target.getAbsolutePath());
93 Policy.error(EFS.ERROR_PARENT_READ_ONLY, message, exception);
94 }
95 }
96
97 @Override
98 public String[] childNames(int options, IProgressMonitor monitor) {
99 String[] names = file.list();
100 return (names == null ? EMPTY_STRING_ARRAY : names);
101 }
102
103 /*
104 * detect if the path is potential builddir
105 */
106 private boolean isPotentialBuildDir(String path) {
107 boolean ret = true;
108 for (int i=0; i < BBSession.BUILDDIR_INDICATORS.length && ret == true; i++) {
109 if((new File(path + BBSession.BUILDDIR_INDICATORS[i])).exists() == false) {
110 ret=false;
111 break;
112 }
113 }
114 return ret;
115 }
116
117 /*
118 * try to find items for ignoreList
119 */
120 private void updateIgnorePaths(String path, List list) {
121 if(isPotentialBuildDir(path)) {
122 BBSession config = null;
123 try {
124 ShellSession shell = new ShellSession(ShellSession.SHELL_TYPE_BASH, new File(root),
125 ProjectInfoHelper.getInitScriptPath(root) + " " + path, null);
126 config = new BBSession(shell, root, true);
127 config.initialize();
128 } catch(Exception e) {
129 e.printStackTrace();
130 return;
131 }
132 if (config.get("TMPDIR") == null || config.get("DL_DIR") == null || config.get("SSTATE_DIR") == null) {
133 //wrong guess about the buildDir
134 return;
135 }else {
136 if(!list.contains(config.get("TMPDIR"))) {
137 list.add(config.get("TMPDIR"));
138 }
139 if(!list.contains(config.get("DL_DIR"))) {
140 list.add(config.get("DL_DIR"));
141 }
142 if(!list.contains(config.get("SSTATE_DIR"))) {
143 list.add(config.get("SSTATE_DIR"));
144 }
145 }
146 }
147 }
148
149 @Override
150 public IFileStore[] childStores(int options, IProgressMonitor monitor) throws CoreException {
151 String[] children = childNames(options, monitor);
152 IFileStore[] wrapped = new IFileStore[children.length];
153
154 for (int i = 0; i < wrapped.length; i++) {
155 String fullPath = file.toString() +File.separatorChar + children[i];
156
157 updateIgnorePaths(fullPath, ignorePaths);
158 if (ignorePaths.contains(fullPath)) {
159 wrapped[i] = getDeadChild(children[i]);
160 } else {
161 wrapped[i] = getChild(children[i]);
162 }
163 }
164
165 return wrapped;
166 }
167
168 @Override
169 public void copy(IFileStore destFile, int options, IProgressMonitor monitor) throws CoreException {
170 if (destFile instanceof OEFile) {
171 File source = file;
172 File destination = ((OEFile) destFile).file;
173 //handle case variants on a case-insensitive OS, or copying between
174 //two equivalent files in an environment that supports symbolic links.
175 //in these nothing needs to be copied (and doing so would likely lose data)
176 try {
177 if (source.getCanonicalFile().equals(destination.getCanonicalFile())) {
178 //nothing to do
179 return;
180 }
181 } catch (IOException e) {
182 String message = NLS.bind(Messages.couldNotRead, source.getAbsolutePath());
183 Policy.error(EFS.ERROR_READ, message, e);
184 }
185 }
186 //fall through to super implementation
187 super.copy(destFile, options, monitor);
188 }
189
190 @Override
191 public void delete(int options, IProgressMonitor monitor) throws CoreException {
192 if (monitor == null)
193 monitor = new NullProgressMonitor();
194 else
195 monitor = new NullProgressMonitor();
196 try {
197 monitor.beginTask(NLS.bind(Messages.deleting, this), 200);
198 String message = Messages.deleteProblem;
199 MultiStatus result = new MultiStatus(Policy.PI_FILE_SYSTEM, EFS.ERROR_DELETE, message, null);
200
201 //don't allow Eclipse to delete entire OE directory
202
203 if (!isProject()) {
204 internalDelete(file, filePath, result, monitor);
205 }
206
207 if (!result.isOK())
208 throw new CoreException(result);
209 } finally {
210 monitor.done();
211 }
212 }
213
214 @Override
215 public boolean equals(Object obj) {
216 if (!(obj instanceof OEFile))
217 return false;
218
219 OEFile otherFile = (OEFile) obj;
220
221 return file.equals(otherFile.file);
222 }
223
224 @Override
225 public IFileInfo fetchInfo(int options, IProgressMonitor monitor) {
226 //in-lined non-native implementation
227 FileInfo info = new FileInfo(file.getName());
228 final long lastModified = file.lastModified();
229 if (lastModified <= 0) {
230 //if the file doesn't exist, all other attributes should be default values
231 info.setExists(false);
232 return info;
233 }
234 info.setLastModified(lastModified);
235 info.setExists(true);
236 info.setLength(file.length());
237 info.setDirectory(file.isDirectory());
238 info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, file.exists() && !file.canWrite());
239 info.setAttribute(EFS.ATTRIBUTE_HIDDEN, file.isHidden());
240 return info;
241 }
242
243 @Override
244 public IFileStore getChild(IPath path) {
245 return new OEFile(new File(file, path.toOSString()), ignorePaths, root);
246 }
247
248 @Override
249 public IFileStore getChild(String name) {
250 return new OEFile(new File(file, name), ignorePaths, root);
251 }
252
253 private IFileStore getDeadChild(String name) {
254 return new OEIgnoreFile(new File(file, name));
255 }
256
257 /*
258 * (non-Javadoc)
259 * @see org.eclipse.core.filesystem.IFileStore#getFileSystem()
260 */
261 @Override
262 public IFileSystem getFileSystem() {
263 return OEFileSystem.getInstance();
264 }
265
266 @Override
267 public String getName() {
268 return file.getName();
269 }
270
271 @Override
272 public IFileStore getParent() {
273 File parent = file.getParentFile();
274 return parent == null ? null : new OEFile(parent, ignorePaths, root);
275 }
276
277 @Override
278 public int hashCode() {
279 return file.hashCode();
280 }
281
282 /**
283 * Deletes the given file recursively, adding failure info to
284 * the provided status object. The filePath is passed as a parameter
285 * to optimize java.io.File object creation.
286 */
287 private boolean internalDelete(File target, String pathToDelete, MultiStatus status, IProgressMonitor monitor) {
288 //first try to delete - this should succeed for files and symbolic links to directories
289 if (target.delete() || !target.exists())
290 return true;
291 if (target.isDirectory()) {
292 monitor.subTask(NLS.bind(Messages.deleting, target));
293 String[] list = target.list();
294 if (list == null)
295 list = EMPTY_STRING_ARRAY;
296 int parentLength = pathToDelete.length();
297 boolean failedRecursive = false;
298 for (int i = 0, imax = list.length; i < imax; i++) {
299 //optimized creation of child path object
300 StringBuffer childBuffer = new StringBuffer(parentLength + list[i].length() + 1);
301 childBuffer.append(pathToDelete);
302 childBuffer.append(File.separatorChar);
303 childBuffer.append(list[i]);
304 String childName = childBuffer.toString();
305 // try best effort on all children so put logical OR at end
306 failedRecursive = !internalDelete(new java.io.File(childName), childName, status, monitor) || failedRecursive;
307 monitor.worked(1);
308 }
309 try {
310 // don't try to delete the root if one of the children failed
311 if (!failedRecursive && target.delete())
312 return true;
313 } catch (Exception e) {
314 // we caught a runtime exception so log it
315 String message = NLS.bind(Messages.couldnotDelete, target.getAbsolutePath());
316 status.add(new Status(IStatus.ERROR, Policy.PI_FILE_SYSTEM, EFS.ERROR_DELETE, message, e));
317 return false;
318 }
319 }
320 //if we got this far, we failed
321 String message = null;
322 if (fetchInfo().getAttribute(EFS.ATTRIBUTE_READ_ONLY))
323 message = NLS.bind(Messages.couldnotDeleteReadOnly, target.getAbsolutePath());
324 else
325 message = NLS.bind(Messages.couldnotDelete, target.getAbsolutePath());
326 status.add(new Status(IStatus.ERROR, Policy.PI_FILE_SYSTEM, EFS.ERROR_DELETE, message, null));
327 return false;
328 }
329
330 @Override
331 public boolean isParentOf(IFileStore other) {
332 if (!(other instanceof OEFile))
333 return false;
334 String thisPath = filePath;
335 String thatPath = ((OEFile) other).filePath;
336 int thisLength = thisPath.length();
337 int thatLength = thatPath.length();
338 //if equal then not a parent
339 if (thisLength >= thatLength)
340 return false;
341 if (getFileSystem().isCaseSensitive()) {
342 if (thatPath.indexOf(thisPath) != 0)
343 return false;
344 } else {
345 if (thatPath.toLowerCase().indexOf(thisPath.toLowerCase()) != 0)
346 return false;
347 }
348 //The common portion must end with a separator character for this to be a parent of that
349 return thisPath.charAt(thisLength - 1) == File.separatorChar || thatPath.charAt(thisLength) == File.separatorChar;
350 }
351
352 /**
353 * @return
354 */
355 private boolean isProject() {
356 return this.file.toString().equals(root);
357 }
358
359 @Override
360 public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
361 boolean shallow = (options & EFS.SHALLOW) != 0;
362 //must be a directory
363 if (shallow)
364 file.mkdir();
365 else
366 file.mkdirs();
367 if (!file.isDirectory()) {
368 checkReadOnlyParent(file, null);
369 String message = NLS.bind(Messages.failedCreateWrongType, filePath);
370 Policy.error(EFS.ERROR_WRONG_TYPE, message);
371 }
372 return this;
373 }
374
375 @Override
376 public void move(IFileStore destFile, int options, IProgressMonitor monitor) throws CoreException {
377 if (!(destFile instanceof OEFile)) {
378 super.move(destFile, options, monitor);
379 return;
380 }
381 File source = file;
382 File destination = ((OEFile) destFile).file;
383 boolean overwrite = (options & EFS.OVERWRITE) != 0;
384 monitor = Policy.monitorFor(monitor);
385 try {
386 monitor.beginTask(NLS.bind(Messages.moving, source.getAbsolutePath()), 10);
387 //this flag captures case renaming on a case-insensitive OS, or moving
388 //two equivalent files in an environment that supports symbolic links.
389 //in these cases we NEVER want to delete anything
390 boolean sourceEqualsDest = false;
391 try {
392 sourceEqualsDest = source.getCanonicalFile().equals(destination.getCanonicalFile());
393 } catch (IOException e) {
394 String message = NLS.bind(Messages.couldNotMove, source.getAbsolutePath());
395 Policy.error(EFS.ERROR_WRITE, message, e);
396 }
397 if (!sourceEqualsDest && !overwrite && destination.exists()) {
398 String message = NLS.bind(Messages.fileExists, destination.getAbsolutePath());
399 Policy.error(EFS.ERROR_EXISTS, message);
400 }
401 if (source.renameTo(destination)) {
402 // double-check to ensure we really did move
403 // since java.io.File#renameTo sometimes lies
404 if (!sourceEqualsDest && source.exists()) {
405 // XXX: document when this occurs
406 if (destination.exists()) {
407 // couldn't delete the source so remove the destination and throw an error
408 // XXX: if we fail deleting the destination, the destination (root) may still exist
409 new OEFile(destination, ignorePaths, root).delete(EFS.NONE, null);
410 String message = NLS.bind(Messages.couldnotDelete, source.getAbsolutePath());
411 Policy.error(EFS.ERROR_DELETE, message);
412 }
413 // source exists but destination doesn't so try to copy below
414 } else {
415 if (!destination.exists()) {
416 // neither the source nor the destination exist. this is REALLY bad
417 String message = NLS.bind(Messages.failedMove, source.getAbsolutePath(), destination.getAbsolutePath());
418 Policy.error(EFS.ERROR_WRITE, message);
419 }
420 //the move was successful
421 monitor.worked(10);
422 return;
423 }
424 }
425 // for some reason renameTo didn't work
426 if (sourceEqualsDest) {
427 String message = NLS.bind(Messages.couldNotMove, source.getAbsolutePath());
428 Policy.error(EFS.ERROR_WRITE, message, null);
429 }
430 // fall back to default implementation
431 super.move(destFile, options, Policy.subMonitorFor(monitor, 10));
432 } finally {
433 monitor.done();
434 }
435 }
436
437 @Override
438 public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException {
439 monitor = Policy.monitorFor(monitor);
440 try {
441 monitor.beginTask("", 1); //$NON-NLS-1$
442 return new FileInputStream(file);
443 } catch (FileNotFoundException e) {
444 String message;
445 if (!file.exists())
446 message = NLS.bind(Messages.fileNotFound, filePath);
447 else if (file.isDirectory())
448 message = NLS.bind(Messages.notAFile, filePath);
449 else
450 message = NLS.bind(Messages.couldNotRead, filePath);
451 Policy.error(EFS.ERROR_READ, message, e);
452 return null;
453 } finally {
454 monitor.done();
455 }
456 }
457
458 @Override
459 public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException {
460 monitor = Policy.monitorFor(monitor);
461 try {
462 monitor.beginTask("", 1); //$NON-NLS-1$
463 return new FileOutputStream(file, (options & EFS.APPEND) != 0);
464 } catch (FileNotFoundException e) {
465 checkReadOnlyParent(file, e);
466 String message;
467 String path = filePath;
468 if (file.isDirectory())
469 message = NLS.bind(Messages.notAFile, path);
470 else
471 message = NLS.bind(Messages.couldNotWrite, path);
472 Policy.error(EFS.ERROR_WRITE, message, e);
473 return null;
474 } finally {
475 monitor.done();
476 }
477 }
478
479 @Override
480 public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
481 boolean success = true;
482
483 //native does not currently set last modified
484 if ((options & EFS.SET_LAST_MODIFIED) != 0)
485 success &= file.setLastModified(info.getLastModified());
486 if (!success && !file.exists())
487 Policy.error(EFS.ERROR_NOT_EXISTS, NLS.bind(Messages.fileNotFound, filePath));
488 }
489
490 /* (non-Javadoc)
491 * @see org.eclipse.core.filesystem.provider.FileStore#toLocalFile(int, org.eclipse.core.runtime.IProgressMonitor)
492 */
493 @Override
494 public File toLocalFile(int options, IProgressMonitor monitor) throws CoreException {
495 if (options == EFS.CACHE)
496 return super.toLocalFile(options, monitor);
497 return file;
498 }
499
500 /* (non-Javadoc)
501 * @see org.eclipse.core.filesystem.IFileStore#toString()
502 */
503 @Override
504 public String toString() {
505 return file.toString();
506 }
507
508 /* (non-Javadoc)
509 * @see org.eclipse.core.filesystem.IFileStore#toURI()
510 */
511 @Override
512 public URI toURI() {
513 return URIUtil.toURI(filePath);
514 }
515}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystem.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystem.java
new file mode 100644
index 0000000..f0bf449
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystem.java
@@ -0,0 +1,78 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.filesystem;
12
13import java.io.File;
14import java.net.URI;
15import java.util.ArrayList;
16import java.util.Hashtable;
17import java.util.List;
18import java.util.Map;
19
20import org.eclipse.core.filesystem.IFileStore;
21import org.eclipse.core.filesystem.IFileSystem;
22import org.eclipse.core.filesystem.provider.FileSystem;
23
24import org.yocto.bc.bitbake.BBSession;
25import org.yocto.bc.ui.Activator;
26
27/**
28 * A filesystem that ignores specific OE directories that contain derived information.
29 * @author kgilmer
30 *
31 */
32public class OEFileSystem extends FileSystem {
33
34 private static IFileSystem ref;
35 public static IFileSystem getInstance() {
36 return ref;
37 }
38
39 private Map fileStoreCache;
40
41 public OEFileSystem() {
42 ref = this;
43 fileStoreCache = new Hashtable();
44 }
45
46 @Override
47 public IFileStore getStore(URI uri) {
48
49 OEFile uf = (OEFile) fileStoreCache.get(uri);
50
51 if (uf == null) {
52 BBSession config = null;
53 try {
54 config = Activator.getBBSession(uri.getPath());
55 config.initialize();
56 } catch (Exception e) {
57 e.printStackTrace();
58 return new OEIgnoreFile(new File(uri.getPath()));
59 }
60
61 if (config.get("TMPDIR") == null || config.get("DL_DIR") == null || config.get("SSTATE_DIR")== null) {
62 throw new RuntimeException("Invalid local.conf: TMPDIR or DL_DIR or SSTATE_DIR undefined.");
63 }
64
65 List ignoreList = new ArrayList();
66
67 //These directories are ignored because they contain too many files for Eclipse to handle efficiently.
68 ignoreList.add(config.get("TMPDIR"));
69 ignoreList.add(config.get("DL_DIR"));
70 ignoreList.add(config.get("SSTATE_DIR"));
71
72 uf = new OEFile(new File(uri.getPath()), ignoreList, uri.getPath());
73 fileStoreCache.put(uri, uf);
74 }
75
76 return uf;
77 }
78}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystemContributor.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystemContributor.java
new file mode 100644
index 0000000..4ac2998
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEFileSystemContributor.java
@@ -0,0 +1,30 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.filesystem;
12
13import java.net.URI;
14
15import org.eclipse.swt.widgets.Shell;
16import org.eclipse.ui.ide.fileSystem.FileSystemContributor;
17
18public class OEFileSystemContributor extends FileSystemContributor {
19
20 @Override
21 public URI browseFileSystem(String initialPath, Shell shell) {
22 return null;
23 }
24
25 @Override
26 public URI getURI(String string) {
27 return super.getURI(string);
28 }
29
30}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEIgnoreFile.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEIgnoreFile.java
new file mode 100644
index 0000000..8643309
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/OEIgnoreFile.java
@@ -0,0 +1,133 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.filesystem;
12
13import java.io.File;
14import java.io.InputStream;
15import java.io.OutputStream;
16import java.net.URI;
17
18import org.eclipse.core.filesystem.IFileInfo;
19import org.eclipse.core.filesystem.IFileStore;
20import org.eclipse.core.filesystem.IFileSystem;
21import org.eclipse.core.filesystem.provider.FileInfo;
22import org.eclipse.core.runtime.CoreException;
23import org.eclipse.core.runtime.IPath;
24import org.eclipse.core.runtime.IProgressMonitor;
25
26public class OEIgnoreFile implements IFileStore {
27
28 private final File file;
29
30 public OEIgnoreFile(File file) {
31 this.file = file;
32 }
33
34 public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
35
36 return new IFileInfo[0];
37 }
38
39 public String[] childNames(int options, IProgressMonitor monitor) throws CoreException {
40 return new String[0];
41 }
42
43 public IFileStore[] childStores(int options, IProgressMonitor monitor) throws CoreException {
44
45 return new IFileStore[0];
46 }
47
48 public void copy(IFileStore destination, int options, IProgressMonitor monitor) throws CoreException {
49 // TODO Auto-generated method stub
50
51 }
52
53 public void delete(int options, IProgressMonitor monitor) throws CoreException {
54 // TODO Auto-generated method stub
55
56 }
57
58 public IFileInfo fetchInfo() {
59 // TODO Auto-generated method stub
60 return new FileInfo(file.getName());
61 }
62
63 public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
64 return new FileInfo(file.getName());
65 }
66
67 public Object getAdapter(Class adapter) {
68 // TODO Auto-generated method stub
69 return null;
70 }
71
72 public IFileStore getChild(IPath path) {
73 // TODO Auto-generated method stub
74 return null;
75 }
76
77
78
79 public IFileStore getChild(String name) {
80 return null;
81 }
82
83 public IFileSystem getFileSystem() {
84 // TODO Auto-generated method stub
85 return OEFileSystem.getInstance();
86 }
87
88 public String getName() {
89 return file.getName();
90 }
91
92 public IFileStore getParent() {
93 // TODO Auto-generated method stub
94 return null;
95 }
96
97 public boolean isParentOf(IFileStore other) {
98 // TODO Auto-generated method stub
99 return false;
100 }
101
102 public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
103 return null;
104 }
105
106 public void move(IFileStore destination, int options, IProgressMonitor monitor) throws CoreException {
107 }
108
109 public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException {
110 return null;
111 }
112
113 public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException {
114 return null;
115 }
116
117 public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
118 }
119
120 public File toLocalFile(int options, IProgressMonitor monitor) throws CoreException {
121 return file;
122 }
123
124 public URI toURI() {
125 return file.toURI();
126 }
127
128 public IFileStore getFileStore(IPath path) {
129 return null;
130 }
131
132
133}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Policy.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Policy.java
new file mode 100644
index 0000000..84c0f32
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/filesystem/Policy.java
@@ -0,0 +1,108 @@
1/*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
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 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.filesystem;
12
13import java.io.IOException;
14import java.io.InputStream;
15import java.io.OutputStream;
16import java.util.Date;
17
18import org.eclipse.core.runtime.CoreException;
19import org.eclipse.core.runtime.IProgressMonitor;
20import org.eclipse.core.runtime.NullProgressMonitor;
21import org.eclipse.core.runtime.OperationCanceledException;
22import org.eclipse.core.runtime.Status;
23import org.eclipse.core.runtime.SubProgressMonitor;
24
25import org.yocto.bc.ui.Activator;
26
27/**
28 * Grab bag of utility methods for the file system plugin
29 */
30public class Policy {
31
32 /**
33 * General debug flag for the plugin
34 */
35 public static boolean DEBUG = false;
36
37 public static final String PI_FILE_SYSTEM = "org.eclipse.core.filesystem"; //$NON-NLS-1$
38
39 public static void checkCanceled(IProgressMonitor monitor) {
40 if (monitor.isCanceled())
41 throw new OperationCanceledException();
42 }
43
44 /**
45 * Print a debug message to the console.
46 * Pre-pend the message with the current date and the name of the current thread.
47 */
48 public static void debug(String message) {
49 StringBuffer buffer = new StringBuffer();
50 buffer.append(new Date(System.currentTimeMillis()));
51 buffer.append(" - ["); //$NON-NLS-1$
52 buffer.append(Thread.currentThread().getName());
53 buffer.append("] "); //$NON-NLS-1$
54 buffer.append(message);
55 System.out.println(buffer.toString());
56 }
57
58 public static void error(int code, String message) throws CoreException {
59 error(code, message, null);
60 }
61
62 public static void error(int code, String message, Throwable exception) throws CoreException {
63 int severity = code == 0 ? 0 : 1 << (code % 100 / 33);
64 throw new CoreException(new Status(severity, PI_FILE_SYSTEM, code, message, exception));
65 }
66
67 public static void log(int severity, String message, Throwable t) {
68 if (message == null)
69 message = ""; //$NON-NLS-1$
70 Activator.getDefault().getLog().log(new Status(severity, PI_FILE_SYSTEM, 1, message, t));
71 }
72
73 public static IProgressMonitor monitorFor(IProgressMonitor monitor) {
74 return monitor == null ? new NullProgressMonitor() : monitor;
75 }
76
77 /**
78 * Closes a stream and ignores any resulting exception.
79 */
80 public static void safeClose(InputStream in) {
81 try {
82 if (in != null)
83 in.close();
84 } catch (IOException e) {
85 //ignore
86 }
87 }
88
89 /**
90 * Closes a stream and ignores any resulting exception.
91 */
92 public static void safeClose(OutputStream out) {
93 try {
94 if (out != null)
95 out.close();
96 } catch (IOException e) {
97 //ignore
98 }
99 }
100
101 public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) {
102 if (monitor == null)
103 return new NullProgressMonitor();
104 if (monitor instanceof NullProgressMonitor)
105 return monitor;
106 return new SubProgressMonitor(monitor, ticks);
107 }
108}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/IModelElement.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/IModelElement.java
new file mode 100644
index 0000000..2892df5
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/IModelElement.java
@@ -0,0 +1,15 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.model;
12
13public interface IModelElement {
14 public void initialize() throws Exception;
15}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/ProjectInfo.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/ProjectInfo.java
new file mode 100644
index 0000000..3af1e2a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/model/ProjectInfo.java
@@ -0,0 +1,48 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.model;
12
13
14public class ProjectInfo implements IModelElement {
15 private String name;
16 private String location;
17 private String init;
18
19 public ProjectInfo() {
20 }
21
22 public String getInitScriptPath() {
23 return init;
24 }
25 public String getProjectName() {
26 return name;
27 }
28 public String getRootPath() {
29 return location;
30 }
31 public void initialize() throws Exception {
32 name = new String();
33 location = new String();
34 init = new String();
35 }
36
37 public void setInitScriptPath(String init) {
38 this.init = init;
39 }
40
41 public void setLocation(String location) {
42 this.location = location;
43 }
44
45 public void setName(String name) {
46 this.name = name;
47 }
48}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/perspectives/BitbakeCommanderPerspective.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/perspectives/BitbakeCommanderPerspective.java
new file mode 100644
index 0000000..b9ddcb6
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/perspectives/BitbakeCommanderPerspective.java
@@ -0,0 +1,89 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.perspectives;
12
13import org.eclipse.ui.IFolderLayout;
14import org.eclipse.ui.IPageLayout;
15import org.eclipse.ui.IPerspectiveFactory;
16import org.eclipse.ui.console.IConsoleConstants;
17
18import org.yocto.bc.ui.views.RecipeView;
19
20public class BitbakeCommanderPerspective implements IPerspectiveFactory {
21
22 private IPageLayout factory;
23
24 public BitbakeCommanderPerspective() {
25 super();
26 }
27
28 private void addActionSets() {
29 factory.addActionSet("org.yocto.bc.ui.actionSet");
30 factory.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET); // NON-NLS-1
31 }
32
33 private void addNewWizardShortcuts() {
34 factory.addNewWizardShortcut("org.yocto.bc.ui.wizards.NewRecipeWizard");// NON-NLS-1
35 //factory.addNewWizardShortcut("org.yocto.bc.ui.wizards.newproject.NewBBCProjectWizard");// NON-NLS-1
36 factory.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");// NON-NLS-1
37 }
38
39 private void addPerspectiveShortcuts() {
40 // factory.addPerspectiveShortcut("org.eclipse.team.ui.TeamSynchronizingPerspective");
41 // //NON-NLS-1
42 // factory.addPerspectiveShortcut("org.eclipse.team.cvs.ui.cvsPerspective");
43 // //NON-NLS-1
44 factory.addPerspectiveShortcut("org.eclipse.ui.resourcePerspective"); // NON-NLS-1
45 }
46
47 private void addViews() {
48 IFolderLayout bottom = factory.createFolder("bottomRight", // NON-NLS-1
49 IPageLayout.BOTTOM, 0.75f, factory.getEditorArea());
50
51 bottom.addView(IPageLayout.ID_PROBLEM_VIEW);
52 bottom.addView("org.eclipse.team.ui.GenericHistoryView"); // NON-NLS-1
53 bottom.addPlaceholder(IConsoleConstants.ID_CONSOLE_VIEW);
54
55 IFolderLayout topLeft = factory.createFolder("topLeft", // NON-NLS-1
56 IPageLayout.LEFT, 0.25f, factory.getEditorArea());
57 topLeft.addView(IPageLayout.ID_RES_NAV);
58 //llu detach RecipeView
59 //topLeft.addView(RecipeView.ID_VIEW); // NON-NLS-1
60
61 }
62
63 private void addViewShortcuts() {
64 // factory.addShowViewShortcut("org.eclipse.ant.ui.views.AntView");
65 // //NON-NLS-1
66 // factory.addShowViewShortcut("org.eclipse.team.ccvs.ui.AnnotateView");
67 // //NON-NLS-1
68 // factory.addShowViewShortcut("org.eclipse.pde.ui.DependenciesView");
69 // //NON-NLS-1
70 // factory.addShowViewShortcut("org.eclipse.jdt.junit.ResultView");
71 // //NON-NLS-1
72 factory.addShowViewShortcut("org.eclipse.team.ui.GenericHistoryView"); // NON-NLS-1
73 factory.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW);
74 // factory.addShowViewShortcut(JavaUI.ID_PACKAGES);
75 factory.addShowViewShortcut(IPageLayout.ID_RES_NAV);
76 // factory.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
77 // factory.addShowViewShortcut(IPageLayout.ID_OUTLINE);
78 }
79
80 public void createInitialLayout(IPageLayout factory) {
81 this.factory = factory;
82 addViews();
83 addActionSets();
84 addNewWizardShortcuts();
85 addPerspectiveShortcuts();
86 addViewShortcuts();
87 }
88
89}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/popup/actions/NewAction.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/popup/actions/NewAction.java
new file mode 100644
index 0000000..3bdf5d3
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/popup/actions/NewAction.java
@@ -0,0 +1,43 @@
1package org.yocto.bc.ui.popup.actions;
2
3import org.eclipse.jface.action.IAction;
4import org.eclipse.jface.dialogs.MessageDialog;
5import org.eclipse.jface.viewers.ISelection;
6import org.eclipse.swt.widgets.Shell;
7import org.eclipse.ui.IActionDelegate;
8import org.eclipse.ui.IObjectActionDelegate;
9import org.eclipse.ui.IWorkbenchPart;
10
11public class NewAction implements IObjectActionDelegate {
12
13 /**
14 * Constructor for Action1.
15 */
16 public NewAction() {
17 super();
18 }
19
20 /**
21 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
22 */
23 public void setActivePart(IAction action, IWorkbenchPart targetPart) {
24 }
25
26 /**
27 * @see IActionDelegate#run(IAction)
28 */
29 public void run(IAction action) {
30 Shell shell = new Shell();
31 MessageDialog.openInformation(
32 shell,
33 "Yocto Project BitBake Commander UI Plug-in",
34 "New Action was executed.");
35 }
36
37 /**
38 * @see IActionDelegate#selectionChanged(IAction, ISelection)
39 */
40 public void selectionChanged(IAction action, ISelection selection) {
41 }
42
43}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeContentProvider.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeContentProvider.java
new file mode 100644
index 0000000..7e29e7a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeContentProvider.java
@@ -0,0 +1,60 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.views;
12
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.List;
16
17import org.eclipse.core.resources.IProject;
18import org.eclipse.core.resources.IProjectNature;
19import org.eclipse.core.resources.ResourcesPlugin;
20import org.eclipse.core.runtime.CoreException;
21import org.eclipse.jface.viewers.IStructuredContentProvider;
22import org.eclipse.jface.viewers.Viewer;
23
24import org.yocto.bc.bitbake.BBSession;
25import org.yocto.bc.ui.Activator;
26import org.yocto.bc.ui.builder.BitbakeCommanderNature;
27
28class RecipeContentProvider implements IStructuredContentProvider {
29 public void dispose() {
30 }
31
32 public Object[] getElements(Object parent) {
33 List recipes = new ArrayList();
34 IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
35 IProjectNature nature = null;
36 for (int i = 0; i < projects.length; ++i) {
37 try {
38 if (projects[i].isOpen() && projects[i].hasNature(BitbakeCommanderNature.NATURE_ID)) {
39 recipes.addAll(getRecipesFromProject(projects[i]));
40 }
41 } catch (CoreException e) {
42 // TODO Auto-generated catch block
43 e.printStackTrace();
44 } catch (Exception e) {
45 // TODO Auto-generated catch block
46 e.printStackTrace();
47 }
48 }
49
50 return recipes.toArray();
51 }
52
53 private Collection getRecipesFromProject(IProject project) throws Exception {
54 BBSession session = Activator.getBBSession(project.getLocationURI().getPath(), null);
55 return session.getRecipeFiles(project);
56 }
57
58 public void inputChanged(Viewer v, Object oldInput, Object newInput) {
59 }
60} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeView.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeView.java
new file mode 100644
index 0000000..fdbd8e0
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/views/RecipeView.java
@@ -0,0 +1,165 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.views;
12
13import org.eclipse.core.resources.IFile;
14import org.eclipse.jface.action.Action;
15import org.eclipse.jface.action.IMenuListener;
16import org.eclipse.jface.action.IMenuManager;
17import org.eclipse.jface.action.IToolBarManager;
18import org.eclipse.jface.action.MenuManager;
19import org.eclipse.jface.action.Separator;
20import org.eclipse.jface.viewers.DoubleClickEvent;
21import org.eclipse.jface.viewers.IDoubleClickListener;
22import org.eclipse.jface.viewers.ISelection;
23import org.eclipse.jface.viewers.IStructuredSelection;
24import org.eclipse.jface.viewers.ITableLabelProvider;
25import org.eclipse.jface.viewers.LabelProvider;
26import org.eclipse.jface.viewers.TableViewer;
27import org.eclipse.jface.viewers.ViewerSorter;
28import org.eclipse.swt.SWT;
29import org.eclipse.swt.graphics.Image;
30import org.eclipse.swt.widgets.Composite;
31import org.eclipse.swt.widgets.Menu;
32import org.eclipse.ui.IActionBars;
33import org.eclipse.ui.ISharedImages;
34import org.eclipse.ui.IWorkbenchActionConstants;
35import org.eclipse.ui.PartInitException;
36import org.eclipse.ui.PlatformUI;
37import org.eclipse.ui.part.FileEditorInput;
38import org.eclipse.ui.part.ViewPart;
39
40import org.yocto.bc.ui.editors.bitbake.BitBakeFileEditor;
41
42public class RecipeView extends ViewPart {
43 class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
44 public Image getColumnImage(Object obj, int index) {
45 return getImage(obj);
46 }
47
48 public String getColumnText(Object obj, int index) {
49
50 if (obj instanceof IFile) {
51 return ((IFile) obj).getName();
52 }
53
54 return getText(obj);
55 }
56
57 @Override
58 public Image getImage(Object obj) {
59 return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
60 }
61 }
62 public static final String ID_VIEW = "org.yocto.bc.ui.views.RecipeView";
63private TableViewer viewer;
64
65 /* private Action action1;
66 private Action action2;
67 */ private Action doubleClickAction;
68
69 private void contributeToActionBars() {
70 IActionBars bars = getViewSite().getActionBars();
71 fillLocalPullDown(bars.getMenuManager());
72 fillLocalToolBar(bars.getToolBarManager());
73 }
74
75 @Override
76 public void createPartControl(Composite parent) {
77 viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
78 viewer.setContentProvider(new RecipeContentProvider());
79 viewer.setLabelProvider(new ViewLabelProvider());
80 viewer.setSorter(new ViewerSorter());
81 viewer.setInput(getViewSite());
82 makeActions();
83 hookContextMenu();
84 hookDoubleClickAction();
85 contributeToActionBars();
86 }
87
88 private void fillContextMenu(IMenuManager manager) {
89/* manager.add(action1);
90 manager.add(action2);
91*/ // Other plug-ins can contribute there actions here
92 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
93 }
94
95 private void fillLocalPullDown(IMenuManager manager) {
96/* manager.add(action1);
97 manager.add(new Separator());
98 manager.add(action2);
99*/ }
100
101 private void fillLocalToolBar(IToolBarManager manager) {
102/* manager.add(action1);
103 manager.add(action2);
104*/ }
105
106 private void hookContextMenu() {
107 MenuManager menuMgr = new MenuManager("#PopupMenu");
108 menuMgr.setRemoveAllWhenShown(true);
109 menuMgr.addMenuListener(new IMenuListener() {
110 public void menuAboutToShow(IMenuManager manager) {
111 RecipeView.this.fillContextMenu(manager);
112 }
113 });
114 Menu menu = menuMgr.createContextMenu(viewer.getControl());
115 viewer.getControl().setMenu(menu);
116 getSite().registerContextMenu(menuMgr, viewer);
117 }
118
119 private void hookDoubleClickAction() {
120 viewer.addDoubleClickListener(new IDoubleClickListener() {
121 public void doubleClick(DoubleClickEvent event) {
122 doubleClickAction.run();
123 }
124 });
125 }
126
127 private void makeActions() {
128/* action1 = new Action() {
129 public void run() {
130 }
131 };
132 action1.setText("Action 1");
133 action1.setToolTipText("Action 1 tooltip");
134 action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
135
136 action2 = new Action() {
137 public void run() {
138 }
139 };
140 action2.setText("Action 2");
141 action2.setToolTipText("Action 2 tooltip");
142 action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
143*/ doubleClickAction = new Action() {
144 @Override
145 public void run() {
146 ISelection selection = viewer.getSelection();
147 Object obj = ((IStructuredSelection) selection).getFirstElement();
148
149 if (obj instanceof IFile) {
150 try {
151 RecipeView.this.getViewSite().getPage().openEditor(new FileEditorInput((IFile) obj), BitBakeFileEditor.EDITOR_ID);
152 } catch (PartInitException e) {
153 // TODO Auto-generated catch block
154 e.printStackTrace();
155 }
156 }
157 }
158 };
159 }
160
161 @Override
162 public void setFocus() {
163 viewer.getControl().setFocus();
164 }
165} \ No newline at end of file
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/BitbakeRecipeUIElement.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/BitbakeRecipeUIElement.java
new file mode 100644
index 0000000..9699117
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/BitbakeRecipeUIElement.java
@@ -0,0 +1,145 @@
1/*******************************************************************************
2 * Copyright (c) 2011 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.wizards;
12
13import org.eclipse.jface.viewers.ISelection;
14import org.eclipse.swt.widgets.Text;
15import java.util.ArrayList;
16
17public class BitbakeRecipeUIElement {
18
19 private String container;
20 private String file;
21 private String description;
22 private String license;
23 private String checksum;
24 private String homepage;
25 private String author;
26 private String section;
27 private String srcuri;
28 private String md5sum;
29 private String sha256sum;
30 private String metaDir;
31 private ArrayList inheritance;
32
33 public BitbakeRecipeUIElement()
34 {
35 this.container = "";
36 this.file = "";
37 this.description = "";
38 this.license = "";
39 this.checksum = "";
40 this.homepage = "";
41 this.author = "";
42 this.section = "";
43 this.srcuri = "";
44 this.md5sum = "";
45 this.sha256sum = "";
46 this.inheritance = new ArrayList();
47 this.metaDir = "";
48 }
49
50 public String getContainer() {
51 return container;
52 }
53 public void setContainer(String value) {
54 this.container = value;
55 }
56 public String getFile() {
57 return file;
58 }
59 public void setFile(String value) {
60 this.file = value;
61 }
62 public String getDescription() {
63 return description;
64 }
65
66 public void setDescription(String value) {
67 this.description = value;
68 }
69
70 public String getLicense() {
71 return license;
72 }
73
74 public void setLicense(String value) {
75 this.license = value;
76 }
77
78 public String getChecksum() {
79 return checksum;
80 }
81 public void setChecksum(String value) {
82 this.checksum = value;
83 }
84
85 public String getHomePage() {
86 return homepage;
87 }
88
89 public void setHomePage(String value) {
90 this.homepage = value;
91 }
92
93 public String getAuthor() {
94 return author;
95 }
96
97 public void setAuthor(String value) {
98 this.author = value;
99 }
100
101 public String getSection() {
102 return section;
103 }
104 public void setSection(String value) {
105 this.section = value;
106 }
107 public String getSrcuri() {
108 return srcuri;
109 }
110 public void setSrcuri(String value) {
111 this.srcuri = value;
112 }
113
114 public String getMd5sum() {
115 return md5sum;
116 }
117
118 public void setMd5sum(String value) {
119 this.md5sum = value;
120 }
121
122 public String getsha256sum() {
123 return sha256sum;
124 }
125
126 public void setSha256sum(String value) {
127 this.sha256sum = value;
128 }
129
130 public ArrayList<String> getInheritance() {
131 return inheritance;
132 }
133
134 public void setInheritance(ArrayList<String> value) {
135 this.inheritance = value;
136 }
137
138 public String getMetaDir() {
139 return metaDir;
140 }
141
142 public void setMetaDir(String value) {
143 metaDir = value;
144 }
145}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizard.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizard.java
new file mode 100644
index 0000000..8b47498
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizard.java
@@ -0,0 +1,56 @@
1package org.yocto.bc.ui.wizards;
2import java.util.Map;
3
4import org.eclipse.jface.wizard.Wizard;
5import org.eclipse.swt.widgets.Composite;
6
7
8
9public abstract class FiniteStateWizard extends Wizard {
10 private boolean finishable = false;
11 private boolean canFinish = false;
12
13 public FiniteStateWizard() {
14 }
15
16 public abstract boolean performFinish();
17
18 /**
19 * @return Returns if the wizard is finishable in its current state.
20 */
21 public boolean isFinishable() {
22 return finishable;
23 }
24 /**
25 * @param finishable Change the finish state of the wizard.
26 */
27 public void setFinishable(boolean finishable) {
28 this.finishable = finishable;
29 }
30
31 /* (non-Javadoc)
32 * @see org.eclipse.jface.wizard.IWizard#createPageControls(org.eclipse.swt.widgets.Composite)
33 */
34 public void createPageControls(Composite pageContainer) {
35 super.createPageControls(pageContainer);
36 }
37
38 /*
39 * (non-Javadoc) Method declared on IWizard.
40 */
41 public boolean canFinish() {
42 if (canFinish)
43 return true;
44 return super.canFinish();
45 }
46
47 public void setCanFinish(boolean canFinish) {
48 this.canFinish = canFinish;
49 }
50
51 /**
52 * Retrive the model object from the wizard.
53 * @return
54 */
55 public abstract Map getModel();
56}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizardPage.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizardPage.java
new file mode 100644
index 0000000..a83a389
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/FiniteStateWizardPage.java
@@ -0,0 +1,149 @@
1package org.yocto.bc.ui.wizards;
2import java.util.Map;
3
4import org.eclipse.jface.viewers.ISelectionChangedListener;
5import org.eclipse.jface.viewers.SelectionChangedEvent;
6import org.eclipse.jface.wizard.WizardPage;
7import org.eclipse.swt.events.ModifyEvent;
8import org.eclipse.swt.events.ModifyListener;
9import org.eclipse.swt.events.SelectionEvent;
10import org.eclipse.swt.events.SelectionListener;
11import org.eclipse.swt.widgets.Composite;
12import org.eclipse.swt.widgets.Event;
13import org.eclipse.swt.widgets.Listener;
14
15public abstract class FiniteStateWizardPage extends WizardPage {
16 protected Map model = null;
17 protected FiniteStateWizard wizard = null;
18 private static boolean previousState = false;
19 /**
20 * @param pageName
21 */
22 protected FiniteStateWizardPage(String name, Map model) {
23 super(name);
24 this.model = model;
25 this.setPageComplete(false);
26 }
27
28 /*
29 * (non-Javadoc)
30 *
31 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
32 */
33 public abstract void createControl(Composite parent);
34
35 protected void setModelWizard() {
36 if (wizard == null) {
37 wizard = (FiniteStateWizard)FiniteStateWizardPage.this.getWizard();
38 }
39 }
40
41 /**
42 * Add page validation logic here. Returning <code>true</code> means that
43 * the page is complete and the user can go to the next page.
44 *
45 * @return
46 */
47 protected abstract boolean validatePage();
48
49 /**
50 * This method should be implemented by ModelWizardPage classes. This method
51 * is called after the <code>validatePage()</code> returns successfully.
52 * Update the model with the contents of the controls on the page.
53 */
54 protected abstract void updateModel();
55
56 /**
57 * Helper method to see if a field has some sort of text in it.
58 * @param value
59 * @return
60 */
61 protected boolean hasContents(String value) {
62 if (value == null || value.length() == 0) {
63 return false;
64 }
65
66 return true;
67 }
68
69 /**
70 * This method is called right before a page is displayed.
71 * This occurs on user action (Next/Back buttons).
72 */
73 public abstract void pageDisplay();
74
75 /**
76 * This method is called on the concrete WizardPage after the user has
77 * gone to the page after.
78 */
79 public abstract void pageCleanup();
80
81 /* (non-Javadoc)
82 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
83 */
84 public void setVisible(boolean arg0) {
85
86 if (!arg0 && previousState) {
87 pageCleanup();
88 } else if (arg0 && !previousState) {
89 pageDisplay();
90 } else if (arg0 && previousState) {
91 pageDisplay();
92 }
93
94 previousState = arg0;
95
96 super.setVisible(arg0);
97 }
98
99 public class ValidationListener implements SelectionListener, ModifyListener, Listener, ISelectionChangedListener {
100
101 /*
102 * (non-Javadoc)
103 *
104 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
105 */
106 public void widgetSelected(SelectionEvent e) {
107 validate();
108 }
109
110 /*
111 * (non-Javadoc)
112 *
113 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
114 */
115 public void widgetDefaultSelected(SelectionEvent e) {
116 }
117
118 /*
119 * (non-Javadoc)
120 *
121 * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
122 */
123 public void modifyText(ModifyEvent e) {
124 validate();
125 }
126
127 public void validate() {
128 if (validatePage()) {
129 updateModel();
130 setPageComplete(true);
131 return;
132 }
133
134 setPageComplete(false);
135 }
136
137 /* (non-Javadoc)
138 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
139 */
140 public void handleEvent(Event event) {
141
142 validate();
143 }
144
145 public void selectionChanged(SelectionChangedEvent event) {
146 validate();
147 }
148 }
149}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizard.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizard.java
new file mode 100644
index 0000000..14b268b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/NewBitBakeFileRecipeWizard.java
@@ -0,0 +1,215 @@
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 java.io.ByteArrayInputStream;
15import java.io.IOException;
16import java.io.InputStream;
17import java.io.File;
18import java.lang.reflect.InvocationTargetException;
19import java.util.ArrayList;
20
21import org.eclipse.core.resources.IContainer;
22import org.eclipse.core.resources.IFile;
23import org.eclipse.core.resources.IResource;
24import org.eclipse.core.resources.IWorkspaceRoot;
25import org.eclipse.core.resources.ResourcesPlugin;
26import org.eclipse.core.runtime.CoreException;
27import org.eclipse.core.runtime.IProgressMonitor;
28import org.eclipse.core.runtime.IStatus;
29import org.eclipse.core.runtime.Path;
30import org.eclipse.core.runtime.Status;
31import org.eclipse.jface.dialogs.MessageDialog;
32import org.eclipse.jface.operation.IRunnableWithProgress;
33import org.eclipse.jface.viewers.ISelection;
34import org.eclipse.jface.viewers.IStructuredSelection;
35import org.eclipse.jface.wizard.Wizard;
36import org.eclipse.ui.INewWizard;
37import org.eclipse.ui.IWorkbench;
38import org.eclipse.ui.IWorkbenchPage;
39import org.eclipse.ui.IWorkbenchWizard;
40import org.eclipse.ui.PartInitException;
41import org.eclipse.ui.PlatformUI;
42import org.eclipse.ui.ide.IDE;
43
44import org.yocto.bc.bitbake.BBLanguageHelper;
45
46public class NewBitBakeFileRecipeWizard extends Wizard implements INewWizard {
47 private NewBitBakeFileRecipeWizardPage page;
48 private ISelection selection;
49
50 public NewBitBakeFileRecipeWizard() {
51 super();
52 setNeedsProgressMonitor(true);
53 }
54
55 @Override
56 public void addPages() {
57 page = new NewBitBakeFileRecipeWizardPage(selection);
58 addPage(page);
59 }
60
61 private void doFinish(BitbakeRecipeUIElement element, IProgressMonitor monitor) throws CoreException {
62 String fileName = element.getFile();
63 monitor.beginTask("Creating " + fileName, 2);
64 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
65 IResource resource = root.findMember(new Path(element.getContainer()));
66 if (!resource.exists() || !(resource instanceof IContainer)) {
67 throwCoreException("Container \"" + element.getContainer() + "\" does not exist.");
68 }
69 IContainer container = (IContainer) resource;
70
71 // If the extension wasn't specified, assume .bb
72 if (!fileName.endsWith(".bb") && !fileName.endsWith(".inc") && !fileName.endsWith(".conf")) {
73 fileName = fileName + ".bb";
74 }
75
76 final IFile file = container.getFile(new Path(fileName));
77 try {
78 InputStream stream = openContentStream(element);
79 if (file.exists()) {
80 file.setContents(stream, true, true, monitor);
81 } else {
82 file.create(stream, true, monitor);
83 }
84 stream.close();
85 } catch (IOException e) {
86 }
87 monitor.worked(1);
88 monitor.setTaskName("Opening file for editing...");
89 getShell().getDisplay().asyncExec(new Runnable() {
90 public void run() {
91 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
92 try {
93 IDE.openEditor(page, file, true);
94 } catch (PartInitException e) {
95 }
96 }
97 });
98 monitor.worked(1);
99 }
100
101 /**
102 * We will accept the selection in the workbench to see if we can initialize
103 * from it.
104 *
105 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
106 */
107 public void init(IWorkbench workbench, IStructuredSelection selection) {
108 this.selection = selection;
109 }
110
111 /**
112 * We will initialize file contents with a sample text.
113 * @param srcuri
114 * @param author
115 * @param homepage
116 * @param license
117 * @param description
118 * @param fileName
119 * @param newPage
120 */
121
122 private InputStream openContentStream(BitbakeRecipeUIElement element) {
123
124 StringBuffer sb = new StringBuffer();
125
126 sb.append("DESCRIPTION = \"" + element.getDescription() + "\"\n");
127
128 if (element.getAuthor().length() > 0) {
129 sb.append("AUTHOR = \"" + element.getAuthor() + "\"\n");
130 }
131
132 if (element.getHomePage().length() > 0) {
133 sb.append("HOMEPAGE = \"" + element.getHomePage() + "\"\n");
134 }
135
136 if (element.getSection().length() > 0) {
137 sb.append("SECTION = \"" + element.getSection() + "\"\n");
138 }
139
140 if (element.getLicense().length() > 0) {
141 sb.append("LICENSE = \"" + element.getLicense() + "\"\n");
142 }
143
144 if (element.getChecksum().length() > 0) {
145 sb.append("LIC_FILES_CHKSUM = \"" + element.getChecksum() + "\"\n");
146 }
147
148 if (element.getSrcuri().length() > 0) {
149 sb.append("SRC_URI = \"" + element.getSrcuri() + "\"\n");
150 }
151
152 if (element.getMd5sum().length() > 0) {
153 sb.append("SRC_URI[md5sum] = \"" + element.getMd5sum() + "\"\n");
154 }
155
156 if (element.getsha256sum().length() > 0) {
157 sb.append("SRC_URI[sha256sum] = \"" + element.getsha256sum() + "\"\n");
158 }
159
160 ArrayList<String> inheritance = element.getInheritance();
161 if (!inheritance.isEmpty()) {
162 Object ia[] = inheritance.toArray();
163 String inheritance_str = "inherit ";
164 for(int i=0; i<ia.length; i++)
165 inheritance_str += ((String) ia[i]) + " ";
166 sb.append(inheritance_str);
167 }
168 sb.append("\n");
169
170 return new ByteArrayInputStream(sb.toString().getBytes());
171 }
172
173 @Override
174 public boolean performFinish() {
175 final BitbakeRecipeUIElement element = page.getUIElement();
176
177 IRunnableWithProgress op = new IRunnableWithProgress() {
178 public void run(IProgressMonitor monitor) throws InvocationTargetException {
179 try {
180 doFinish(element, monitor);
181 File temp_dir = new File(element.getMetaDir() + "/temp");
182 if (temp_dir.exists()) {
183 File working_dir = new File(element.getMetaDir());
184
185 String rm_cmd = "rm -rf temp";
186 final Process process = Runtime.getRuntime().exec(rm_cmd, null, working_dir);
187 int returnCode = process.waitFor();
188 if (returnCode != 0) {
189 throw new Exception("Failed to clean up the temp dir");
190 }
191 }
192 } catch (Exception e) {
193 throw new InvocationTargetException(e);
194 } finally {
195 monitor.done();
196 }
197 }
198 };
199 try {
200 getContainer().run(true, false, op);
201 } catch (InterruptedException e) {
202 return false;
203 } catch (InvocationTargetException e) {
204 Throwable realException = e.getTargetException();
205 MessageDialog.openError(getShell(), "Error", realException.getMessage());
206 return false;
207 }
208 return true;
209 }
210
211 private void throwCoreException(String message) throws CoreException {
212 IStatus status = new Status(IStatus.ERROR, "org.yocto.bc.ui", IStatus.OK, message, null);
213 throw new CoreException(status);
214 }
215} \ No newline at end of file
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
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/BBCProjectPage.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/BBCProjectPage.java
new file mode 100644
index 0000000..71ea70c
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/BBCProjectPage.java
@@ -0,0 +1,236 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.wizards.importProject;
12
13import java.io.File;
14import java.util.Map;
15
16import org.eclipse.core.resources.IProject;
17import org.eclipse.core.resources.IResource;
18import org.eclipse.core.resources.IWorkspaceRoot;
19import org.eclipse.core.resources.ResourcesPlugin;
20import org.eclipse.core.runtime.IStatus;
21import org.eclipse.swt.SWT;
22import org.eclipse.swt.events.SelectionAdapter;
23import org.eclipse.swt.events.SelectionEvent;
24import org.eclipse.swt.layout.GridData;
25import org.eclipse.swt.layout.GridLayout;
26import org.eclipse.swt.widgets.Button;
27import org.eclipse.swt.widgets.Composite;
28import org.eclipse.swt.widgets.DirectoryDialog;
29import org.eclipse.swt.widgets.FileDialog;
30import org.eclipse.swt.widgets.Label;
31import org.eclipse.swt.widgets.Text;
32import org.eclipse.ui.PlatformUI;
33
34import org.yocto.bc.ui.wizards.FiniteStateWizardPage;
35
36/**
37 * Main property page for new project wizard.
38 * @author kgilmer
39 *
40 */
41public class BBCProjectPage extends FiniteStateWizardPage {
42
43 private class FileOpenSelectionAdapter extends SelectionAdapter {
44 @Override
45 public void widgetSelected(SelectionEvent e) {
46 FileDialog fd = new FileDialog(PlatformUI.getWorkbench()
47 .getDisplay().getActiveShell(), SWT.OPEN);
48
49 fd.setText("Open Configuration Script");
50 fd.setFilterPath(txtProjectLocation.getText());
51
52 String selected = fd.open();
53
54 if (selected != null) {
55 txtInit.setText(selected);
56 updateModel();
57 }
58 }
59 }
60 public static final String PAGE_TITLE = "Yocto Project BitBake Commander Project";
61 private Text txtProjectLocation;
62
63 private Text txtInit;
64 private ValidationListener validationListener;
65 private Text txtProjectName;
66
67 public BBCProjectPage(Map model) {
68 super(PAGE_TITLE, model);
69 setTitle("Create new Yocto Project BitBake Commander project");
70 setMessage("Enter information to create a BitBake Commander project.");
71 }
72
73 public void createControl(Composite parent) {
74 GridData gdFillH = new GridData(GridData.FILL_HORIZONTAL);
75 GridData gdVU = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
76
77 Composite top = new Composite(parent, SWT.NONE);
78 top.setLayoutData(new GridData(GridData.FILL_BOTH));
79 top.setLayout(new GridLayout());
80
81 Composite projectNameComp = new Composite(top, SWT.NONE);
82 GridData gdProjName = new GridData(GridData.FILL_HORIZONTAL);
83 projectNameComp.setLayoutData(gdProjName);
84 projectNameComp.setLayout(new GridLayout(2, false));
85 Label lblProjectName = new Label(projectNameComp, SWT.NONE);
86 lblProjectName.setText("N&ame:");
87
88 txtProjectName = new Text(projectNameComp, SWT.BORDER);
89 txtProjectName.setLayoutData(gdFillH);
90 txtProjectName.setFocus();
91 validationListener = new ValidationListener();
92
93 txtProjectName.addModifyListener(validationListener);
94
95 Label lblProjectLocation = new Label(projectNameComp, SWT.None);
96 lblProjectLocation.setText("&Location:");
97
98 Composite locComposite = new Composite(projectNameComp, SWT.NONE);
99 GridData gd = new GridData(GridData.VERTICAL_ALIGN_END
100 | GridData.FILL_HORIZONTAL);
101 gd.horizontalIndent = 0;
102 locComposite.setLayoutData(gd);
103 GridLayout gl = new GridLayout(2, false);
104 gl.marginWidth = 0;
105 locComposite.setLayout(gl);
106
107 txtProjectLocation = new Text(locComposite, SWT.BORDER);
108 txtProjectLocation.setLayoutData(gdFillH);
109 txtProjectLocation.addModifyListener(validationListener);
110
111 Button button = new Button(locComposite, SWT.PUSH);
112 button.setText("Browse...");
113 button.addSelectionListener(new SelectionAdapter() {
114 @Override
115 public void widgetSelected(SelectionEvent e) {
116 handleBrowse();
117 }
118 });
119
120 Label lblInit = new Label(projectNameComp, SWT.NONE);
121 lblInit.setText("Init Script:");
122
123 Composite initComposite = new Composite(projectNameComp, SWT.NONE);
124 gd = new GridData(GridData.VERTICAL_ALIGN_END
125 | GridData.FILL_HORIZONTAL);
126 gd.horizontalIndent = 0;
127 initComposite.setLayoutData(gd);
128 gl = new GridLayout(2, false);
129 gl.marginWidth = 0;
130 initComposite.setLayout(gl);
131
132 txtInit = new Text(initComposite, SWT.BORDER);
133 GridData gdi = new GridData(GridData.FILL_HORIZONTAL);
134 txtInit.setLayoutData(gdi);
135 txtInit.addModifyListener(validationListener);
136
137 Button btnLoadInit = new Button(initComposite, SWT.PUSH);
138 btnLoadInit.setLayoutData(gdVU);
139 btnLoadInit.setText("Choose...");
140 btnLoadInit.addSelectionListener(new FileOpenSelectionAdapter());
141
142 if (System.getenv("OEROOT") != null) {
143 txtProjectLocation.setText(System.getenv("OEROOT"));
144 }
145
146 setControl(top);
147 }
148
149 private void handleBrowse() {
150 DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.None);
151 String dir = dialog.open();
152 if (dir != null) {
153 txtProjectLocation.setText(dir);
154 }
155 }
156
157 private String getFileSegment(String initScriptPath) {
158 //return the first segment of " " seperated array, or full string if no " " exists
159 return initScriptPath.split(" ")[0];
160 }
161
162 private boolean isValidProjectName(String projectName) {
163 if (projectName.indexOf('$') > -1) {
164 return false;
165 }
166
167 return true;
168 }
169
170
171 @Override
172 public void pageCleanup() {
173 // TODO Auto-generated method stub
174
175 }
176
177 @Override
178 public void pageDisplay() {
179 // TODO Auto-generated method stub
180
181 }
182
183 @Override
184 protected void updateModel() {
185 model.put(ImportYoctoProjectWizard.KEY_NAME, txtProjectName.getText());
186 model.put(ImportYoctoProjectWizard.KEY_LOCATION, txtProjectLocation.getText());
187 model.put(ImportYoctoProjectWizard.KEY_INITPATH, txtInit.getText());
188 }
189
190
191 @Override
192 protected boolean validatePage() {
193 IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot();
194
195 IStatus validate = ResourcesPlugin.getWorkspace().validateName(txtProjectName.getText(), IResource.PROJECT);
196
197 if (!validate.isOK() || !isValidProjectName(txtProjectName.getText())) {
198 setErrorMessage("Invalid project name: " + txtProjectName.getText());
199 return false;
200 }
201
202 IProject proj = wsroot.getProject(txtProjectName.getText());
203 if (proj.exists()) {
204 setErrorMessage("A project with the name " + txtProjectName.getText()
205 + " already exists");
206 return false;
207 }
208
209 if (txtProjectLocation.getText().trim().length() == 0) {
210 setErrorMessage("Set directory that contains Poky tree");
211 return false;
212 }
213
214 File f = new File(txtProjectLocation.getText());
215 if (!f.exists() || !f.isDirectory()) {
216 setErrorMessage("Invalid Directory");
217 return false;
218 }
219
220 if (txtInit.getText().length() == 0) {
221 setErrorMessage("Set configuration file before BitBake is launched.");
222 return false;
223 }
224
225 File f2 = new File(getFileSegment(txtInit.getText()));
226 if (!f2.exists() || f2.isDirectory()) {
227 setErrorMessage("The configuration file is invalid.");
228 return false;
229 }
230
231 setErrorMessage(null);
232 setMessage("All the entries are valid, press \"Finish\" to create the new yocto bitbake project,"+
233 "this will take a while. Please don't interrupt till there's output in the Yocto Console window...");
234 return true;
235 }
236}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/ImportYoctoProjectWizard.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/ImportYoctoProjectWizard.java
new file mode 100644
index 0000000..b1fc841
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/importProject/ImportYoctoProjectWizard.java
@@ -0,0 +1,166 @@
1/*******************************************************************************
2 * Copyright (c) 2011 Intel Corporation.
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 * Intel - initial API and implementation
10 *******************************************************************************/
11package org.yocto.bc.ui.wizards.importProject;
12
13import java.io.IOException;
14import java.io.Writer;
15import java.util.Hashtable;
16import java.util.Map;
17
18import org.eclipse.core.runtime.IStatus;
19import org.eclipse.core.runtime.Status;
20import org.eclipse.jface.viewers.IStructuredSelection;
21import org.eclipse.ui.IImportWizard;
22import org.eclipse.ui.IWorkbench;
23import org.eclipse.ui.IWorkbenchPage;
24import org.eclipse.ui.IWorkbenchWindow;
25import org.eclipse.ui.PlatformUI;
26import org.eclipse.ui.console.ConsolePlugin;
27import org.eclipse.ui.console.IConsole;
28import org.eclipse.ui.console.IConsoleConstants;
29import org.eclipse.ui.console.IConsoleManager;
30import org.eclipse.ui.console.IConsoleView;
31import org.eclipse.ui.console.MessageConsole;
32
33import org.yocto.bc.ui.Activator;
34import org.yocto.bc.ui.model.ProjectInfo;
35import org.yocto.bc.ui.wizards.FiniteStateWizard;
36
37import org.yocto.bc.ui.wizards.newproject.BBConfigurationInitializeOperation;
38import org.yocto.bc.ui.wizards.newproject.CreateBBCProjectOperation;
39
40public class ImportYoctoProjectWizard extends FiniteStateWizard implements IImportWizard {
41 protected final static String KEY_OEROOT = "OEROOT";
42 public static final String KEY_NAME = "NAME";
43 public static final String KEY_LOCATION = "LOCATION";
44 public static final String KEY_INITPATH = "INITPATH";
45 protected static final String KEY_PINFO = "PINFO";
46
47 private Map projectModel;
48 private IWorkbench workbench;
49 private IStructuredSelection selection;
50
51 private MessageConsole myConsole;
52
53 public ImportYoctoProjectWizard() {
54 projectModel = new Hashtable();
55 }
56
57 public Map getModel() {
58 return projectModel;
59 }
60
61 @Override
62 public void addPages() {
63 addPage(new BBCProjectPage(projectModel));
64 //addPage(new ConsolePage(projectModel));
65 }
66
67
68 public boolean performFinish() {
69 ProjectInfo pinfo = new ProjectInfo();
70 pinfo.setInitScriptPath((String) projectModel.get(ImportYoctoProjectWizard.KEY_INITPATH));
71 pinfo.setLocation((String) projectModel.get(ImportYoctoProjectWizard.KEY_LOCATION));
72 pinfo.setName((String) projectModel.get(ImportYoctoProjectWizard.KEY_NAME));
73
74 try {
75 ConsoleWriter cw = new ConsoleWriter();
76 this.getContainer().run(false, false, new BBConfigurationInitializeOperation(pinfo, cw));
77 myConsole.newMessageStream().println(cw.getContents());
78 } catch (Exception e) {
79 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
80 this.getContainer().getCurrentPage().setDescription("Failed to create project: " + e.getMessage());
81 //valid = false;
82 //setPageComplete(valid);
83 return false;
84 }
85
86 //valid = true;
87 projectModel.put(ImportYoctoProjectWizard.KEY_PINFO, pinfo);
88 //setPageComplete(valid);
89 //ProjectInfo pinfo = (ProjectInfo) projectModel.get(KEY_PINFO);
90 Activator.putProjInfo(pinfo.getRootPath(), pinfo);
91 try {
92 getContainer().run(false, false, new CreateBBCProjectOperation(pinfo));
93 } catch (Exception e) {
94 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
95 this.getContainer().getCurrentPage().setDescription("Failed to create project: " + e.getMessage());
96 return false;
97 }
98
99 return true;
100 }
101
102 public void init(IWorkbench workbench, IStructuredSelection selection) {
103 this.workbench = workbench;
104 this.selection = selection;
105 this.setNeedsProgressMonitor(true);
106 setWindowTitle("BitBake Commander Project");
107
108 myConsole = findConsole("Yocto Console");
109 IWorkbench wb = PlatformUI.getWorkbench();
110 IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
111 IWorkbenchPage page = win.getActivePage();
112 String id = IConsoleConstants.ID_CONSOLE_VIEW;
113 try {
114 IConsoleView view = (IConsoleView) page.showView(id);
115 view.display(myConsole);
116 } catch (Exception e) {
117 e.printStackTrace();
118 }
119 }
120
121 private MessageConsole findConsole(String name) {
122 ConsolePlugin plugin = ConsolePlugin.getDefault();
123 IConsoleManager conMan = plugin.getConsoleManager();
124 IConsole[] existing = conMan.getConsoles();
125 for (int i = 0; i < existing.length; i++)
126 if (name.equals(existing[i].getName()))
127 return (MessageConsole) existing[i];
128 // no console found, so create a new one
129 MessageConsole myConsole = new MessageConsole(name, null);
130 conMan.addConsoles(new IConsole[] { myConsole });
131 return myConsole;
132 }
133
134 private class ConsoleWriter extends Writer {
135
136 private StringBuffer sb;
137
138 public ConsoleWriter() {
139 sb = new StringBuffer();
140 }
141 @Override
142 public void close() throws IOException {
143 }
144
145 public String getContents() {
146 return sb.toString();
147 }
148
149 @Override
150 public void flush() throws IOException {
151 }
152
153 @Override
154 public void write(char[] cbuf, int off, int len) throws IOException {
155 //txtConsole.getText().concat(new String(cbuf));
156 sb.append(cbuf);
157 }
158
159 @Override
160 public void write(String str) throws IOException {
161 sb.append(str);
162 }
163
164 }
165
166}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/InstallWizard.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/InstallWizard.java
new file mode 100644
index 0000000..f2cb1da
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/InstallWizard.java
@@ -0,0 +1,404 @@
1package org.yocto.bc.ui.wizards.install;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileDescriptor;
7import java.io.InputStream;
8import java.io.IOException;
9import java.io.InputStreamReader;
10import java.io.OutputStream;
11import java.io.Writer;
12import java.util.ArrayList;
13import java.util.Hashtable;
14import java.util.Map;
15import java.util.regex.Matcher;
16import java.util.regex.Pattern;
17import java.lang.reflect.InvocationTargetException;
18import java.net.URL;
19
20import org.eclipse.core.runtime.IProgressMonitor;
21import org.eclipse.core.runtime.IStatus;
22import org.eclipse.core.runtime.NullProgressMonitor;
23import org.eclipse.core.runtime.Path;
24import org.eclipse.core.runtime.Status;
25import org.eclipse.jface.operation.IRunnableWithProgress;
26import org.eclipse.jface.viewers.IStructuredSelection;
27import org.eclipse.jface.wizard.IWizardPage;
28import org.eclipse.jface.wizard.WizardPage;
29
30import org.eclipse.ui.PlatformUI;
31import org.eclipse.ui.IWorkbench;
32import org.eclipse.ui.IWorkbenchWizard;
33import org.eclipse.ui.IWorkbenchPage;
34import org.eclipse.ui.IWorkbenchWindow;
35import org.eclipse.ui.console.IConsoleConstants;
36import org.eclipse.ui.console.MessageConsole;
37import org.eclipse.ui.console.MessageConsoleStream;
38import org.eclipse.ui.console.ConsolePlugin;
39import org.eclipse.ui.console.IConsoleManager;
40import org.eclipse.ui.console.IConsole;
41import org.eclipse.ui.console.IConsoleView;
42import org.eclipse.ui.progress.IProgressService;
43
44import org.yocto.bc.bitbake.ICommandResponseHandler;
45import org.yocto.bc.bitbake.ShellSession;
46import org.yocto.bc.ui.Activator;
47import org.yocto.bc.ui.model.ProjectInfo;
48import org.yocto.bc.ui.wizards.FiniteStateWizard;
49
50import org.yocto.bc.ui.wizards.newproject.BBConfigurationInitializeOperation;
51import org.yocto.bc.ui.wizards.newproject.CreateBBCProjectOperation;
52
53/**
54 * A wizard for installing a fresh copy of an OE system.
55 *
56 * @author kgilmer
57 *
58 * A Wizard for creating a fresh Yocto bitbake project and new poky build tree from git
59 *
60 * @modified jzhang
61 *
62 */
63public class InstallWizard extends FiniteStateWizard implements
64 IWorkbenchWizard {
65
66 static final String KEY_PINFO = "KEY_PINFO";
67 protected static final String OPTION_MAP = "OPTION_MAP";
68 protected static final String INSTALL_SCRIPT = "INSTALL_SCRIPT";
69 protected static final String INSTALL_DIRECTORY = "Install Directory";
70 protected static final String INIT_SCRIPT = "Init Script";
71
72 protected static final String PROJECT_NAME = "Project Name";
73 protected static final String DEFAULT_INIT_SCRIPT = "oe-init-build-env";
74 protected static final String DEFAULT_INSTALL_DIR = "~/yocto";
75
76 protected static final String GIT_CLONE = "Git Clone";
77 public static final String VALIDATION_FILE = DEFAULT_INIT_SCRIPT;
78
79 private Map model;
80 private MessageConsole myConsole;
81
82 public InstallWizard() {
83 this.model = new Hashtable();
84 model.put(INSTALL_DIRECTORY, DEFAULT_INSTALL_DIR);
85 model.put(INIT_SCRIPT, DEFAULT_INIT_SCRIPT);
86
87 setWindowTitle("Yocto Project BitBake Commander");
88 setNeedsProgressMonitor(true);
89
90 myConsole = findConsole("Yocto Project Console");
91 IWorkbench wb = PlatformUI.getWorkbench();
92 IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
93 IWorkbenchPage page = win.getActivePage();
94 String id = IConsoleConstants.ID_CONSOLE_VIEW;
95 try {
96 IConsoleView view = (IConsoleView) page.showView(id);
97 view.display(myConsole);
98 } catch (Exception e) {
99 e.printStackTrace();
100 }
101 }
102
103 private MessageConsole findConsole(String name) {
104 ConsolePlugin plugin = ConsolePlugin.getDefault();
105 IConsoleManager conMan = plugin.getConsoleManager();
106 IConsole[] existing = conMan.getConsoles();
107 for (int i = 0; i < existing.length; i++)
108 if (name.equals(existing[i].getName()))
109 return (MessageConsole) existing[i];
110 // no console found, so create a new one
111 MessageConsole myConsole = new MessageConsole(name, null);
112 conMan.addConsoles(new IConsole[] { myConsole });
113 return myConsole;
114 }
115
116 public InstallWizard(IStructuredSelection selection) {
117 model = new Hashtable();
118 }
119
120 /*
121 * @Override public IWizardPage getNextPage(IWizardPage page) { if (page
122 * instanceof WelcomePage) { if (model.containsKey(WelcomePage.ACTION_USE))
123 * { return bbcProjectPage; } } else if (page instanceof ProgressPage) {
124 * return bitbakePage; }
125 *
126 * if (super.getNextPage(page) != null) { System.out.println("next page: " +
127 * super.getNextPage(page).getClass().getName()); } else {
128 * System.out.println("end page"); }
129 *
130 * return super.getNextPage(page); }
131 *
132 * @Override public boolean canFinish() { System.out.println("can finish: "
133 * + super.canFinish()); return super.canFinish(); }
134 */
135 @Override
136 public void addPages() {
137 addPage(new OptionsPage(model));
138 }
139
140 @Override
141 public Map getModel() {
142 return model;
143 }
144
145 @Override
146 public boolean performFinish() {
147 BCCommandResponseHandler cmdOut = new BCCommandResponseHandler(
148 myConsole);
149
150 WizardPage page = (WizardPage) getPage("Options");
151 page.setPageComplete(true);
152 Map options = (Map) model;
153 String install_dir = "";
154 if (options.containsKey(INSTALL_DIRECTORY)) {
155 install_dir = (String) options.get(INSTALL_DIRECTORY);
156 }
157
158 try {
159 if (((Boolean)options.get(GIT_CLONE)).booleanValue()) {
160 String []git_clone_cmd = {"git", "clone", "--progress", "git://git.pokylinux.org/poky.git", install_dir};
161 final Pattern pattern = Pattern.compile("^Receiving objects:\\s*(\\d+)%.*");
162
163 this.getContainer().run(true,true,
164 new LongtimeRunningTask("Checking out Yocto git repository",
165 git_clone_cmd, null, null,
166 cmdOut,
167 new ICalculatePercentage() {
168 public float calWorkloadDone(String info) throws IllegalArgumentException {
169 Matcher m=pattern.matcher(info.trim());
170 if(m.matches()) {
171 return new Float(m.group(1)) / 100;
172 }else {
173 throw new IllegalArgumentException();
174 }
175 }
176 }
177 )
178 );
179 }
180
181 if (!cmdOut.hasError()) {
182
183 String initPath = install_dir + "/"
184 + (String) options.get(INIT_SCRIPT);
185 String prjName = (String) options.get(PROJECT_NAME);
186 ProjectInfo pinfo = new ProjectInfo();
187 pinfo.setInitScriptPath(initPath);
188 pinfo.setLocation(install_dir);
189 pinfo.setName(prjName);
190
191 ConsoleWriter cw = new ConsoleWriter();
192 this.getContainer().run(false, false,
193 new BBConfigurationInitializeOperation(pinfo, cw));
194
195 myConsole.newMessageStream().println(cw.getContents());
196
197 model.put(InstallWizard.KEY_PINFO, pinfo);
198 Activator.putProjInfo(pinfo.getRootPath(), pinfo);
199
200 this.getContainer().run(false, false,
201 new CreateBBCProjectOperation(pinfo));
202 return true;
203 }
204 } catch (Exception e) {
205 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
206 IStatus.ERROR, e.getMessage(), e));
207 this.getContainer().getCurrentPage().setDescription(
208 "Failed to create project: " + e.getMessage());
209 }
210 return false;
211 }
212
213 public void init(IWorkbench workbench, IStructuredSelection selection) {
214 }
215
216 private interface ICalculatePercentage {
217 public float calWorkloadDone(String info) throws IllegalArgumentException;
218 }
219
220 private class LongtimeRunningTask implements IRunnableWithProgress {
221 private String []cmdArray;
222 private String []envp;
223 private File dir;
224 private ICommandResponseHandler handler;
225 private Process p;
226 private String taskName;
227 static public final int TOTALWORKLOAD=100;
228 private int reported_workload;
229 ICalculatePercentage cal;
230
231 public LongtimeRunningTask(String taskName,
232 String []cmdArray, String []envp, File dir,
233 ICommandResponseHandler handler,
234 ICalculatePercentage calculator) {
235 this.taskName=taskName;
236 this.cmdArray=cmdArray;
237 this.envp=envp;
238 this.dir=dir;
239 this.handler=handler;
240 this.p=null;
241 this.cal=calculator;
242 }
243
244 private void reportProgress(IProgressMonitor monitor,String info) {
245 if(cal == null) {
246 monitor.worked(1);
247 }else {
248 float percentage;
249 try {
250 percentage=cal.calWorkloadDone(info);
251 } catch (IllegalArgumentException e) {
252 //can't get percentage
253 return;
254 }
255 int delta=(int) (TOTALWORKLOAD * percentage - reported_workload);
256 if( delta > 0 ) {
257 monitor.worked(delta);
258 reported_workload += delta;
259 }
260 }
261 }
262
263 synchronized public void run(IProgressMonitor monitor)
264 throws InvocationTargetException, InterruptedException {
265
266 boolean cancel=false;
267 reported_workload=0;
268
269 try {
270 monitor.beginTask(taskName, TOTALWORKLOAD);
271
272 p=Runtime.getRuntime().exec(cmdArray,envp,dir);
273 BufferedReader inbr = new BufferedReader(new InputStreamReader(p.getInputStream()));
274 BufferedReader errbr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
275 String info;
276 while (!cancel) {
277 if(monitor.isCanceled())
278 {
279 cancel=true;
280 throw new InterruptedException("User Cancelled");
281 }
282
283 info=null;
284 //reading stderr
285 while (errbr.ready()) {
286 info=errbr.readLine();
287 //some application using stderr to print out information
288 handler.response(info, false);
289 }
290 //reading stdout
291 while (inbr.ready()) {
292 info=inbr.readLine();
293 handler.response(info, false);
294 }
295
296 //report progress
297 if(info!=null)
298 reportProgress(monitor,info);
299
300 //check if exit
301 try {
302 int exitValue=p.exitValue();
303 if (exitValue != 0) {
304 handler.response(
305 taskName + " failed with the return value " + new Integer(exitValue).toString(),
306 true);
307 }
308 break;
309 }catch (IllegalThreadStateException e) {
310 }
311
312 Thread.sleep(500);
313 }
314 } catch (IOException e) {
315 throw new InvocationTargetException(e);
316 } finally {
317 monitor.done();
318 if (p != null ) {
319 p.destroy();
320 }
321 }
322 }
323 }
324
325 private class BCCommandResponseHandler implements ICommandResponseHandler {
326 private MessageConsoleStream myConsoleStream;
327 private Boolean errorOccured = false;
328
329 public BCCommandResponseHandler(MessageConsole console) {
330 try {
331 this.myConsoleStream = console.newMessageStream();
332 } catch (Exception e) {
333 e.printStackTrace();
334 }
335 }
336
337 public void printDialog(String msg) {
338 try {
339 myConsoleStream.println(msg);
340 } catch (Exception e) {
341 e.printStackTrace();
342 }
343 }
344
345 public Boolean hasError() {
346 return errorOccured;
347 }
348
349 public void response(String line, boolean isError) {
350 try {
351 if (isError) {
352 myConsoleStream.println(line);
353 errorOccured = true;
354 } else {
355 myConsoleStream.println(line);
356 }
357 } catch (Exception e) {
358 e.printStackTrace();
359 }
360 }
361
362 public void printCmd(String cmd) {
363 try {
364 myConsoleStream.println(cmd);
365 } catch (Exception e) {
366 e.printStackTrace();
367 }
368 }
369 }
370
371 private class ConsoleWriter extends Writer {
372
373 private StringBuffer sb;
374
375 public ConsoleWriter() {
376 sb = new StringBuffer();
377 }
378
379 @Override
380 public void close() throws IOException {
381 }
382
383 public String getContents() {
384 return sb.toString();
385 }
386
387 @Override
388 public void flush() throws IOException {
389 }
390
391 @Override
392 public void write(char[] cbuf, int off, int len) throws IOException {
393 // txtConsole.getText().concat(new String(cbuf));
394 sb.append(cbuf);
395 }
396
397 @Override
398 public void write(String str) throws IOException {
399 sb.append(str);
400 }
401
402 }
403
404}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/OptionsPage.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/OptionsPage.java
new file mode 100644
index 0000000..2844fda
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/install/OptionsPage.java
@@ -0,0 +1,247 @@
1package org.yocto.bc.ui.wizards.install;
2
3import java.io.IOException;
4import java.io.File;
5import java.net.URI;
6import java.util.ArrayList;
7import java.util.Hashtable;
8import java.util.Iterator;
9import java.util.List;
10import java.util.Map;
11
12import org.eclipse.core.resources.IProject;
13import org.eclipse.core.resources.IProjectDescription;
14import org.eclipse.core.resources.IResource;
15import org.eclipse.core.resources.IWorkspaceRoot;
16import org.eclipse.core.resources.ResourcesPlugin;
17import org.eclipse.core.runtime.CoreException;
18import org.eclipse.core.runtime.IStatus;
19import org.eclipse.swt.SWT;
20import org.eclipse.swt.events.SelectionAdapter;
21import org.eclipse.swt.events.SelectionEvent;
22import org.eclipse.swt.layout.GridData;
23import org.eclipse.swt.layout.GridLayout;
24import org.eclipse.swt.widgets.Button;
25import org.eclipse.swt.widgets.Composite;
26import org.eclipse.swt.widgets.Control;
27import org.eclipse.swt.widgets.DirectoryDialog;
28import org.eclipse.swt.widgets.FileDialog;
29import org.eclipse.swt.widgets.Label;
30import org.eclipse.swt.widgets.Text;
31import org.eclipse.ui.PlatformUI;
32
33import org.yocto.bc.ui.wizards.FiniteStateWizard;
34import org.yocto.bc.ui.wizards.FiniteStateWizardPage;
35import org.yocto.bc.ui.wizards.FiniteStateWizardPage.ValidationListener;
36
37/**
38 * Select which flavor of OE is to be installed.
39 *
40 * @author kgilmer
41 *
42 * Setting up the parameters for creating the new Yocto Bitbake project
43 *
44 * @modified jzhang
45 */
46public class OptionsPage extends FiniteStateWizardPage {
47
48 private Map vars;
49 private Composite c1;
50 private Composite top;
51
52 private List controlList;
53 private boolean controlsCreated = false;
54
55 private Text txtProjectLocation;
56
57 private Text txtInit;
58 private ValidationListener validationListener;
59 private Text txtProjectName;
60 private Button gitButton;
61
62 protected OptionsPage(Map model) {
63 super("Options", model);
64 //setTitle("Create new yocto bitbake project");
65 setMessage("Enter these parameters to create new Yocto Project BitBake commander project");
66 }
67
68 @Override
69 public void createControl(Composite parent) {
70 top = new Composite(parent, SWT.None);
71 top.setLayout(new GridLayout());
72 top.setLayoutData(new GridData(GridData.FILL_BOTH));
73
74 GridData gdFillH = new GridData(GridData.FILL_HORIZONTAL);
75 GridData gdVU = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
76
77 Composite projectNameComp = new Composite(top, SWT.NONE);
78 GridData gdProjName = new GridData(GridData.FILL_HORIZONTAL);
79 projectNameComp.setLayoutData(gdProjName);
80 projectNameComp.setLayout(new GridLayout(2, false));
81 Label lblProjectName = new Label(projectNameComp, SWT.NONE);
82 lblProjectName.setText("Project N&ame:");
83
84 txtProjectName = new Text(projectNameComp, SWT.BORDER);
85 txtProjectName.setLayoutData(gdFillH);
86 txtProjectName.setFocus();
87 validationListener = new ValidationListener();
88
89 txtProjectName.addModifyListener(validationListener);
90
91 Label lblProjectLocation = new Label(projectNameComp, SWT.None);
92 lblProjectLocation.setText("&Project Location:");
93
94 Composite locComposite = new Composite(projectNameComp, SWT.NONE);
95 GridData gd = new GridData(GridData.VERTICAL_ALIGN_END
96 | GridData.FILL_HORIZONTAL);
97 gd.horizontalIndent = 0;
98 locComposite.setLayoutData(gd);
99 GridLayout gl = new GridLayout(2, false);
100 gl.marginWidth = 0;
101 locComposite.setLayout(gl);
102
103 txtProjectLocation = new Text(locComposite, SWT.BORDER);
104 txtProjectLocation.setLayoutData(gdFillH);
105 txtProjectLocation.addModifyListener(validationListener);
106
107 Button button = new Button(locComposite, SWT.PUSH);
108 button.setText("Browse...");
109 button.addSelectionListener(new SelectionAdapter() {
110 @Override
111 public void widgetSelected(SelectionEvent e) {
112 handleBrowse();
113 }
114 });
115
116 //Label lblGit = new Label(projectNameComp, SWT.None);
117 //lblGit.setText("Clone from &Git Repository?");
118
119 Composite gitComposite = new Composite(projectNameComp, SWT.NONE);
120 gd = new GridData(GridData.VERTICAL_ALIGN_END
121 | GridData.FILL_HORIZONTAL);
122 gd.horizontalIndent = 0;
123 gitComposite.setLayoutData(gd);
124 gl = new GridLayout(1, false);
125 gl.marginWidth = 0;
126 gitComposite.setLayout(gl);
127
128 gitButton = new Button(gitComposite, SWT.CHECK);
129 gitButton.setText("Clone from Yocto Project &Git Repository");
130 gitButton.setEnabled(true);
131 gitButton.addSelectionListener(validationListener);
132
133 setControl(top);
134 }
135
136 private void handleBrowse() {
137 DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.None);
138 String dir = dialog.open();
139 if (dir != null) {
140 txtProjectLocation.setText(dir);
141 }
142 }
143
144 @Override
145 public void pageCleanup() {
146
147 }
148
149 @Override
150 public void pageDisplay() {
151 }
152
153 @Override
154
155 protected void updateModel() {
156 model.put(InstallWizard.INSTALL_DIRECTORY, txtProjectLocation.getText()+File.separator+txtProjectName.getText());
157 model.put(InstallWizard.PROJECT_NAME, txtProjectName.getText());
158 model.put(InstallWizard.GIT_CLONE, new Boolean(gitButton.getSelection()));
159 }
160
161 private boolean isValidProjectName(String projectName) {
162 if (projectName.indexOf('$') > -1) {
163 return false;
164 }
165
166 return true;
167 }
168 @Override
169 protected boolean validatePage() {
170 IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot();
171
172 IStatus validate = ResourcesPlugin.getWorkspace().validateName(txtProjectName.getText(), IResource.PROJECT);
173
174 if (!validate.isOK() || !isValidProjectName(txtProjectName.getText())) {
175 setErrorMessage("Invalid project name: " + txtProjectName.getText());
176 return false;
177 }
178
179 IProject proj = wsroot.getProject(txtProjectName.getText());
180 if (proj.exists()) {
181 setErrorMessage("A project with the name " + txtProjectName.getText()
182 + " already exists");
183 return false;
184 }
185
186 String projectLoc = txtProjectLocation.getText();
187 File checkProject_dir = new File(projectLoc);
188 if (!checkProject_dir.isDirectory()) {
189 setErrorMessage("The project location directory " + txtProjectLocation.getText() + " is not valid");
190 return false;
191 }
192
193 String projectPath = projectLoc + File.separator+txtProjectName.getText();
194 File git_dir=new File(projectPath);
195 if(!gitButton.getSelection()) {
196 if(!git_dir.isDirectory() || !git_dir.exists()) {
197 setErrorMessage("Directory " + txtProjectLocation.getText()+File.separator+txtProjectName.getText() + " does not exist, please select git clone.");
198 return false;
199 }else if(!new File(projectPath + File.separator + InstallWizard.VALIDATION_FILE).exists()) {
200 setErrorMessage("Directory " + txtProjectLocation.getText()+File.separator+txtProjectName.getText() + " seems invalid, please use other directory or project name.");
201 return false;
202 }
203 }else {
204 // git check
205 if(git_dir.exists()) {
206 setErrorMessage("Directory " + txtProjectLocation.getText()+File.separator+txtProjectName.getText() + " exists, please unselect git clone.");
207 return false;
208 }
209 }
210
211 try {
212 URI location = new URI("file://" + txtProjectLocation.getText()+File.separator+txtProjectName.getText());
213
214 IStatus status = ResourcesPlugin.getWorkspace().validateProjectLocationURI(proj, location);
215 if (!status.isOK()) {
216 setErrorMessage(status.getMessage());
217 return false;
218 }
219 } catch (Exception e) {
220 setErrorMessage("Run into error while trying to validate entries!");
221 return false;
222 }
223 setErrorMessage(null);
224 setMessage("All the entries are valid, press \"Finish\" to start the process, "+
225 "this will take a while. Please don't interrupt till there's output in the Yocto Console window...");
226 return true;
227 }
228
229 private class FileOpenSelectionAdapter extends SelectionAdapter {
230 @Override
231 public void widgetSelected(SelectionEvent e) {
232 FileDialog fd = new FileDialog(PlatformUI.getWorkbench()
233 .getDisplay().getActiveShell(), SWT.OPEN);
234
235 fd.setText("Open Configuration Script");
236 fd.setFilterPath(txtProjectLocation.getText());
237
238 String selected = fd.open();
239
240 if (selected != null) {
241 txtInit.setText(selected);
242 updateModel();
243 }
244 }
245 }
246
247}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/BBConfigurationInitializeOperation.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/BBConfigurationInitializeOperation.java
new file mode 100644
index 0000000..4f15107
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/BBConfigurationInitializeOperation.java
@@ -0,0 +1,50 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.wizards.newproject;
12
13import java.io.Writer;
14import java.lang.reflect.InvocationTargetException;
15
16import org.eclipse.core.runtime.IProgressMonitor;
17import org.eclipse.jface.operation.IRunnableWithProgress;
18
19import org.yocto.bc.bitbake.BBSession;
20import org.yocto.bc.bitbake.ProjectInfoHelper;
21import org.yocto.bc.ui.Activator;
22import org.yocto.bc.ui.model.ProjectInfo;
23
24public class BBConfigurationInitializeOperation implements IRunnableWithProgress {
25
26 private final ProjectInfo pinfo;
27 private final Writer writer;
28
29 public BBConfigurationInitializeOperation(ProjectInfo pinfo) {
30 this.pinfo = pinfo;
31 writer = null;
32 }
33
34 public BBConfigurationInitializeOperation(ProjectInfo pinfo, Writer writer) {
35 this.pinfo = pinfo;
36 this.writer = writer;
37 }
38
39 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
40 BBSession session;
41 try {
42 ProjectInfoHelper.store(pinfo.getRootPath(), pinfo);
43 session = Activator.getBBSession(pinfo.getRootPath(), writer);
44 session.initialize();
45
46 } catch (Exception e) {
47 throw new InvocationTargetException(e);
48 }
49 }
50}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/CreateBBCProjectOperation.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/CreateBBCProjectOperation.java
new file mode 100644
index 0000000..dc0153b
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/newproject/CreateBBCProjectOperation.java
@@ -0,0 +1,102 @@
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 *******************************************************************************/
11package org.yocto.bc.ui.wizards.newproject;
12
13import java.io.IOException;
14import java.lang.reflect.InvocationTargetException;
15import java.net.URI;
16import java.net.URISyntaxException;
17import java.util.Arrays;
18import java.util.Vector;
19
20import org.eclipse.core.resources.IProject;
21import org.eclipse.core.resources.IProjectDescription;
22import org.eclipse.core.resources.IWorkspace;
23import org.eclipse.core.resources.IWorkspaceRoot;
24import org.eclipse.core.resources.ResourcesPlugin;
25import org.eclipse.core.runtime.CoreException;
26import org.eclipse.core.runtime.IProgressMonitor;
27import org.eclipse.core.runtime.IStatus;
28import org.eclipse.core.runtime.QualifiedName;
29import org.eclipse.core.runtime.Status;
30import org.eclipse.ui.actions.WorkspaceModifyOperation;
31
32import org.yocto.bc.bitbake.ProjectInfoHelper;
33import org.yocto.bc.ui.Activator;
34import org.yocto.bc.ui.builder.BitbakeCommanderNature;
35import org.yocto.bc.ui.model.ProjectInfo;
36
37
38/**
39 * Creates a bbc project
40 * @author kgilmer
41 *
42 */
43public class CreateBBCProjectOperation extends WorkspaceModifyOperation {
44
45 public static final String OEFS_SCHEME = "OEFS://";
46 public static final QualifiedName BBC_PROJECT_INIT = new QualifiedName(null, "BBC_PROJECT_INIT");
47 public static void addNatureToProject(IProject proj, String nature_id, IProgressMonitor monitor) throws CoreException {
48 IProjectDescription desc = proj.getDescription();
49 Vector natureIds = new Vector();
50
51 natureIds.add(nature_id);
52 natureIds.addAll(Arrays.asList(desc.getNatureIds()));
53 desc.setNatureIds((String[]) natureIds.toArray(new String[natureIds.size()]));
54
55 proj.setDescription(desc, monitor);
56 }
57
58 private ProjectInfo projInfo;
59
60 public CreateBBCProjectOperation(ProjectInfo projInfo) {
61 this.projInfo = projInfo;
62 }
63
64 protected void addNatures(IProject proj, IProgressMonitor monitor) throws CoreException {
65 addNatureToProject(proj, BitbakeCommanderNature.NATURE_ID, monitor);
66 }
67
68 private IProjectDescription createProjectDescription(IWorkspace workspace, ProjectInfo projInfo2) throws CoreException {
69 IProjectDescription desc = workspace.newProjectDescription(projInfo2.getProjectName());
70
71 try {
72 desc.setLocationURI(new URI(OEFS_SCHEME + projInfo2.getRootPath()));
73 } catch (URISyntaxException e) {
74 throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to load filesystem.", e));
75 }
76
77 return desc;
78 }
79
80 @Override
81 protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
82 IProjectDescription desc = createProjectDescription(ResourcesPlugin.getWorkspace(), projInfo);
83
84 IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot();
85
86 IProject proj = wsroot.getProject(projInfo.getProjectName());
87 proj.create(desc, monitor);
88 try {
89 ProjectInfoHelper.store(proj.getLocationURI().getPath(), projInfo);
90 } catch (IOException e) {
91 throw new InvocationTargetException(e);
92 }
93
94 proj.open(monitor);
95
96 addNatures(proj, monitor);
97 }
98
99 public ProjectInfo getProjectInfo() {
100 return projInfo;
101 }
102}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariablePage.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariablePage.java
new file mode 100644
index 0000000..810a014
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariablePage.java
@@ -0,0 +1,262 @@
1package org.yocto.bc.ui.wizards.variable;
2
3import java.util.Comparator;
4import java.util.Map;
5
6import org.eclipse.jface.viewers.ILabelProviderListener;
7import org.eclipse.jface.viewers.IStructuredContentProvider;
8import org.eclipse.jface.viewers.ITableLabelProvider;
9import org.eclipse.jface.viewers.TableViewer;
10import org.eclipse.jface.viewers.Viewer;
11import org.eclipse.jface.viewers.ViewerFilter;
12import org.eclipse.jface.viewers.ViewerSorter;
13import org.eclipse.swt.SWT;
14import org.eclipse.swt.events.SelectionAdapter;
15import org.eclipse.swt.events.SelectionEvent;
16import org.eclipse.swt.graphics.Image;
17import org.eclipse.swt.layout.GridData;
18import org.eclipse.swt.layout.GridLayout;
19import org.eclipse.swt.widgets.Composite;
20import org.eclipse.swt.widgets.Table;
21import org.eclipse.swt.widgets.TableColumn;
22import org.eclipse.swt.widgets.Text;
23
24import org.yocto.bc.ui.wizards.FiniteStateWizardPage;
25
26/**
27 * The wizard page for the Variable Wizard.
28 * @author kgilmer
29 *
30 */
31public class VariablePage extends FiniteStateWizardPage {
32
33 private Text txtName;
34 private Text txtValue;
35 private TableViewer viewer;
36 private TableColumn c1;
37 private TableColumn c2;
38
39 protected VariablePage(Map model) {
40 super("Yocto Project BitBake Commander", model);
41 setTitle("Yocto Project BitBake Variable Viewer");
42 setDescription("Sort and fitler global BitBake variables by name or value.");
43 }
44
45 @Override
46 public void createControl(Composite parent) {
47 Composite top = new Composite(parent, SWT.None);
48 top.setLayout(new GridLayout(2, true));
49 top.setLayoutData(new GridData(GridData.FILL_BOTH));
50
51 ValidationListener listener = new ValidationListener();
52
53 txtName = new Text(top, SWT.BORDER);
54 txtName.addModifyListener(listener);
55 txtName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
56
57 txtValue = new Text(top, SWT.BORDER);
58 txtValue.addModifyListener(listener);
59 txtValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
60
61 viewer = new TableViewer(top);
62
63 Table table = viewer.getTable();
64 table.setLinesVisible(true);
65 table.setHeaderVisible(true);
66 GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
67 data.heightHint = 200;
68 data.horizontalSpan = 2;
69 table.setLayoutData(data);
70 c1 = new TableColumn(table, SWT.NONE);
71 c1.setText("Name");
72 c1.setWidth(200);
73 c1.addSelectionListener(new SelectionAdapter() {
74 public void widgetSelected(SelectionEvent event) {
75 ((VariableViewerSorter) viewer.getSorter()).doSort(0);
76 viewer.refresh();
77 }
78 });
79
80 c2 = new TableColumn(table, SWT.NONE);
81 c2.setText("Value");
82 c2.setWidth(200);
83 c2.addSelectionListener(new SelectionAdapter() {
84 public void widgetSelected(SelectionEvent event) {
85 ((VariableViewerSorter) viewer.getSorter()).doSort(1);
86 viewer.refresh();
87 }
88 });
89
90 viewer.setContentProvider(new VariableContentProvider());
91 viewer.setLabelProvider(new VariableLabelProvider());
92 viewer.setSorter(new VariableViewerSorter());
93
94 viewer.setFilters(new ViewerFilter[] {new MapViewerFilter()});
95 setControl(top);
96 }
97
98 @Override
99 public void pageCleanup() {
100
101 }
102
103 @Override
104 public void pageDisplay() {
105 viewer.setInput(model);
106 }
107
108 @Override
109 protected void updateModel() {
110 viewer.refresh();
111 }
112
113 @Override
114 protected boolean validatePage() {
115 return true;
116 }
117
118 /**
119 * A content provider for the variable wizard dialog.
120 * @author kgilmer
121 *
122 */
123 private class VariableContentProvider implements IStructuredContentProvider {
124
125 public Object[] getElements(Object inputElement) {
126 return model.keySet().toArray();
127 }
128
129 public void dispose() {
130
131 }
132
133 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
134
135 }
136 }
137
138 /**
139 * A label provider for variable wizard dialog.
140 * @author kgilmer
141 *
142 */
143 private class VariableLabelProvider implements ITableLabelProvider {
144
145 public Image getColumnImage(Object element, int columnIndex) {
146 return null;
147 }
148
149 public String getColumnText(Object element, int columnIndex) {
150 String val;
151
152 switch (columnIndex) {
153 case 0:
154 val = element.toString();
155 break;
156 case 1:
157 val = (String) model.get(element);
158 break;
159 default:
160 val = "";
161 break;
162 }
163
164 return val;
165 }
166
167 public void addListener(ILabelProviderListener listener) {
168
169 }
170
171 public void dispose() {
172
173 }
174
175 public boolean isLabelProperty(Object element, String property) {
176 return false;
177 }
178
179 public void removeListener(ILabelProviderListener listener) {
180
181 }
182
183 }
184
185 /**
186 *
187 * A tableviewer sorter found on the internet.
188 *
189 */
190 class VariableViewerSorter extends ViewerSorter {
191 private static final int ASCENDING = 0;
192
193 private static final int DESCENDING = 1;
194
195 private int column;
196
197 private int direction;
198
199 public void doSort(int column) {
200 if (column == this.column) {
201 // Same column as last sort; toggle the direction
202 direction = 1 - direction;
203 } else {
204 // New column; do an ascending sort
205 this.column = column;
206 direction = ASCENDING;
207 }
208 }
209
210 public int compare(Viewer viewer, Object e1, Object e2) {
211 int rc = 0;
212 Comparator c = this.getComparator();
213 // Determine which column and do the appropriate sort
214 switch (column) {
215 case 0:
216 rc = c.compare(e1, e2);
217 break;
218 case 1:
219 rc = c.compare(model.get(e1), model.get(e2));
220 break;
221 }
222
223 // If descending order, flip the direction
224 if (direction == DESCENDING)
225 rc = -rc;
226
227 return rc;
228 }
229 }
230
231 /**
232 * A filter for the name/value model.
233 * @author kgilmer
234 *
235 */
236 private class MapViewerFilter extends ViewerFilter {
237
238 public MapViewerFilter() {
239 }
240
241 @Override
242 public boolean select(Viewer viewer, Object parentElement, Object element) {
243 String keyFilter = txtName.getText();
244 String valFilter = txtValue.getText();
245
246 String elem = (String) element;
247 String val = (String) model.get(element);
248
249 if (keyFilter.length() > 0 && elem.indexOf(keyFilter) == -1 ) {
250 return false;
251 }
252
253 if (valFilter.length() > 0 && val.indexOf(valFilter) == -1 ) {
254 return false;
255 }
256
257 return true;
258 }
259
260 }
261
262}
diff --git a/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariableWizard.java b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariableWizard.java
new file mode 100644
index 0000000..d1bee1a
--- /dev/null
+++ b/plugins/org.yocto.bc.ui/src/org/yocto/bc/ui/wizards/variable/VariableWizard.java
@@ -0,0 +1,43 @@
1package org.yocto.bc.ui.wizards.variable;
2
3import java.util.Hashtable;
4import java.util.Map;
5
6import org.eclipse.jface.viewers.IStructuredSelection;
7
8import org.yocto.bc.ui.wizards.FiniteStateWizard;
9
10/**
11 * This wizard is used to view, filter, and search for BitBake variables and variable contents.
12 * @author kgilmer
13 *
14 */
15public class VariableWizard extends FiniteStateWizard {
16
17 private Map model;
18
19 public VariableWizard(Map model) {
20 this.model = model;
21 setWindowTitle("Yocto Project BitBake Commander");
22 }
23
24 public VariableWizard(IStructuredSelection selection) {
25 model = new Hashtable();
26 }
27
28 @Override
29 public void addPages() {
30 addPage(new VariablePage(model));
31 }
32
33 @Override
34 public Map getModel() {
35 return model;
36 }
37
38 @Override
39 public boolean performFinish() {
40 return true;
41 }
42
43}