All Classes Namespaces Files Functions Variables
PackageWizard.java
Go to the documentation of this file.
1 package javafxmlpackage.wizards;
2 
3 import org.eclipse.jface.viewers.IStructuredSelection;
4 import org.eclipse.jface.wizard.Wizard;
5 import org.eclipse.ui.INewWizard;
6 import org.eclipse.ui.IWorkbench;
7 import org.eclipse.core.runtime.*;
8 import org.eclipse.jface.operation.*;
9 import java.lang.reflect.InvocationTargetException;
10 import java.util.Calendar;
11 
12 import org.eclipse.jface.dialogs.MessageDialog;
13 import org.eclipse.jface.viewers.ISelection;
14 import org.eclipse.core.resources.*;
15 
16 import java.io.*;
17 import org.eclipse.ui.*;
18 import org.eclipse.ui.ide.IDE;
19 
20 /**
21  *
22  * Wizard, joka luo jyu ohj2 kurssin mukaisen javaFXML packagen.
23  */
24 
25 public class PackageWizard extends Wizard implements INewWizard {
27  private ISelection selection;
28 
29  /**
30  * Constructor for PackageWizard.
31  */
32  public PackageWizard() {
33  super();
34  setNeedsProgressMonitor(true);
35  }
36 
37  /**
38  * Adding the page to the wizard.
39  */
40 
41  @Override
42  public void addPages() {
44  addPage(page);
45  }
46 
47  /**
48  * This method is called when 'Finish' button is pressed in
49  * the wizard. We will create an operation and run it
50  * using wizard as execution context.
51  */
52  @Override
53  public boolean performFinish() {
54  final String containerName = page.getContainerName();
55  final String fileName = page.getFileName();
56  final String packageName = page.getPackageName();
57 
58  IRunnableWithProgress op = new IRunnableWithProgress() {
59  @Override
60  public void run(IProgressMonitor monitor) throws InvocationTargetException {
61  try {
62  doFinish(containerName, packageName, fileName, monitor);
63  } catch (CoreException e) {
64  throw new InvocationTargetException(e);
65  } finally {
66  monitor.done();
67  }
68  }
69  };
70  try {
71  getContainer().run(true, false, op);
72  } catch (InterruptedException e) {
73  return false;
74  } catch (InvocationTargetException e) {
75  Throwable realException = e.getTargetException();
76  MessageDialog.openError(getShell(), "Error", realException.getMessage());
77  return false;
78  }
79  return true;
80  }
81 
82  /**
83  *
84  * Luodaan tiedostot
85  * @param containerName projektin src folder
86  * @param packageName paketin nimi
87  * @param fileName ohjelman nimi
88  * @param monitor eclipse monitori
89  * @throws CoreException eclipse joku core exception varmaanki
90  *
91  */
92 
93  protected void doFinish(
94  String containerName,
95  String packageName,
96  String fileName,
97  IProgressMonitor monitor)
98  throws CoreException {
99  // create a sample file
100 
101  String parsePackageName = packageName.replace('.', '/');
102 
103  String parseFileName = fileName;
104 
105  String vaihdaKirjain = "ÅÄÖåäö"; // näiden on syytä olla yhtä pitkiä
106  String uusiKirjain = "AAOaao"; // tai käyttäjä saa vastaansa exceptioni
107  // ja ohi pääsee korjaamalla ite ääkköset pois nimestä,
108  // joten ei estä pluginin käyttämistä, vaikka joku hölmöilisikin
109 
110  for (int i = 0; i < vaihdaKirjain.length(); i++) {
111  parsePackageName = parsePackageName.replace(vaihdaKirjain.charAt(i), uusiKirjain.charAt(i));
112  parseFileName = parseFileName.replace(vaihdaKirjain.charAt(i), uusiKirjain.charAt(i));
113  }
114 
115  // siivotaa mahdolliset tuplamerkit yksinkertasella algoritmil... ei jaksa miettii mitää
116  StringBuilder sb = new StringBuilder(parsePackageName);
117 
118  while (sb.indexOf("//") != -1) {
119  sb.deleteCharAt(sb.indexOf("//"));
120  }
121 
122  parsePackageName = sb.toString();
123 
124 
125 
126  if (Character.isLowerCase(parseFileName.charAt(0)))
127  parseFileName = Character.toUpperCase(parseFileName.charAt(0)) + parseFileName.substring(1);
128 
129  monitor.beginTask("Creating files...", 2);
130  IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
131  IResource resource = root.findMember(new Path(containerName));
132  if (!resource.exists() || !(resource instanceof IContainer)) {
133  throwCoreException("Project \"" + containerName + "\" does not exist.");
134  }
135 
136  if (resource.getProjectRelativePath().isEmpty()) {
137  throwCoreException("src folder ei kelpaa");
138  }
139 
140 
141  IContainer container = (IContainer) resource;
142  final IFile javaFile = container.getFile(new Path(parsePackageName +"/" +parseFileName + "Main.java"));
143  final IFile controllerFile = container.getFile(new Path(parsePackageName +"/" +parseFileName+ "Controller.java"));
144  final IFile cssFile = container.getFile(new Path(parsePackageName +"/" +parseFileName.toLowerCase()+ ".css"));
145  final IFile viewFile = container.getFile(new Path(parsePackageName +"/" +parseFileName+ "View.fxml"));
146 
147 
148  if (parsePackageName.lastIndexOf('/') == -1) {
149  final IFolder packageF = container.getFolder(new Path(parsePackageName));
150  if (!packageF.exists())
151  packageF.create(false, false, monitor);
152  }
153 
154  else {
155  String[] splitti = parsePackageName.split("/");
156  String pathi = "/";
157  for (int i = 0; i < splitti.length; i++) {
158  if (splitti[i].length() == 0) continue;
159  pathi += splitti[i] + "/";
160  final IFolder packageF = container.getFolder(new Path(pathi));
161  if (!packageF.exists())
162  packageF.create(false, false, monitor);
163  }
164  }
165 
166 
167  try (InputStream stream = openContentStream(1, parsePackageName, parseFileName, fileName)){
168  cssFile.create(stream, true, monitor);
169 
170  } catch (IOException e) {
171  //
172  }
173 
174  try (InputStream stream = openContentStream(2, parsePackageName, parseFileName, fileName)){
175  controllerFile.create(stream, true, monitor);
176 
177  } catch (IOException e) {
178  //
179  }
180 
181  try (InputStream stream = openContentStream(3, parsePackageName, parseFileName, fileName)){
182  javaFile.create(stream, true, monitor);
183 
184  } catch (IOException e) {
185  //
186  }
187 
188  try (InputStream stream = openContentStream(4, parsePackageName, parseFileName, fileName)){
189  viewFile.create(stream, true, monitor);
190 
191  } catch (IOException e) {
192  //
193  }
194 
195  // tarkistetaan, että on javafx projekti
196  tarkistaProjekti(resource.getParent(), monitor);
197 
198  monitor.worked(1);
199  monitor.setTaskName("Opening file for editing...");
200  getShell().getDisplay().asyncExec(new Runnable() {
201  @Override
202  public void run() {
203  IWorkbenchPage sivu =
204  PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
205  try {
206  IDE.openEditor(sivu, javaFile, true);
207  } catch (PartInitException e) {
208  //
209  }
210  }
211  });
212  monitor.worked(1);
213  }
214 
215  private void tarkistaProjekti(IContainer cont, IProgressMonitor monitor) throws CoreException {
216  //
217  if (!cont.getProjectRelativePath().isEmpty()) return; // TODO: ollaan jossai muualla kuin projektin juuressa..
218  final IFile fxbuildFile = cont.getFile(new Path("/build.fxbuild"));
219  if (fxbuildFile.exists()) {
220  // javafx projekti, joten lähetää pois
221  return;
222  }
223  try (InputStream stream = openFxprojektStream(cont)){
224  fxbuildFile.create(stream, true, monitor);
225 
226  } catch (IOException e) {
227  //
228  }
229 
230  // muokataa .project filua
231 
232  final IFile projectFile = cont.getFile(new Path(".project"));
233  if (!fxbuildFile.exists()) {
234  // .projectia ei ole, toivottavasti käyttäjä tietää mitä on tekemässä...
235  return;
236  }
237 
238  try (InputStream stream = projectFile.getContents()) {
239  //
240  StringBuilder sisalto = getStringBuilder(stream);
241 
242  String mihin = "</buildSpec>";
243  int index = sisalto.lastIndexOf(mihin);
244  if (index == -1) return;
245  String lisattava =
246  " <buildCommand>"+System.lineSeparator()+
247  " <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>"+System.lineSeparator()+
248  " <arguments>"+System.lineSeparator()+
249  " </arguments>"+System.lineSeparator()+
250  " </buildCommand>"+System.lineSeparator()+"\t";
251  sisalto.insert(index, lisattava);
252 
253  mihin = "<nature>";
254  index = sisalto.lastIndexOf(mihin);
255  if (index == -1) return;
256  lisattava =
257  "<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>"+System.lineSeparator()+"\t\t";
258  sisalto.insert(index, lisattava);
259  projectFile.setContents(new ByteArrayInputStream(sisalto.toString().getBytes()), true, true, monitor);
260  } catch (IOException e) {
261  //
262  }
263 
264  // muokataan .classpathia
265  final IFile classpathFile = cont.getFile(new Path(".classpath"));
266  if (!fxbuildFile.exists()) {
267  // .classpathia ei ole, toivottavasti käyttäjä tietää mitä on tekemässä...
268  return;
269  }
270  try (InputStream stream = classpathFile.getContents()) {
271  //
272  StringBuilder sisalto = getStringBuilder(stream);
273 
274  String mihin = "<classpathentry";
275  int index = sisalto.lastIndexOf(mihin);
276  if (index == -1) return;
277  String lisattava =
278  "<classpathentry kind=\"con\" path=\"org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER\"/>"+System.lineSeparator()+"\t";
279  sisalto.insert(index, lisattava);
280 
281  classpathFile.setContents(new ByteArrayInputStream(sisalto.toString().getBytes()), true, true, monitor);
282  } catch (IOException e) {
283  //
284  }
285 
286  }
287 
288  /**
289  * muutetaa inputstream stringiksi, jotta voidaan muokkaa sitä
290  * @param stream is
291  * @return is -> string
292  * @throws IOException
293  */
294  private StringBuilder getStringBuilder(InputStream stream) throws IOException {
295  //
296  StringBuilder sb = new StringBuilder();
297  String s;
298  try (BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
299  while ((s = br.readLine()) != null) {
300  // joudutaa lisäämää rivinvaihto uusiks, mutta tämä varmaa helpoin tapa kääntää inpustream stringiks
301  sb.append(s + System.lineSeparator());
302  }
303  }
304  return sb;
305  }
306 
307  /**
308  * Filujen sisältö... tää ny siin plugin wizardis oli tehty tällei, että tehää samalla tavalla
309  * pienellä omalla jollai.. - iha varmuuden vuoks
310  *
311  * monesko - 1 = .css tiedosto, 2 = Controller tiedosto, 3 = .java tiedosto, 4 = xml tiedosto
312  */
313 
314  private InputStream openContentStream(int monesko, String packageName, String fileName, String alkupFileName) {
315 
316  Calendar aika = Calendar.getInstance();
317 
318 
319  String contents = "";
320  String parsePackageName = packageName.replace('/', '.');
321  switch (monesko) {
322 
323  case 1: contents = "/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */";
324  break;
325  case 2:
326  contents =
327  "package "+parsePackageName+";"+System.lineSeparator()+
328  System.lineSeparator()+
329  "/**"+System.lineSeparator()+
330  " * @author "+System.getProperty("user.name").toString()+System.lineSeparator()+
331  " * @version "+aika.get(Calendar.DAY_OF_MONTH)+"."+(aika.get(Calendar.MONTH) + 1)+"."+aika.get(Calendar.YEAR)+System.lineSeparator()+
332  " *"+System.lineSeparator()+
333  " */"+System.lineSeparator()+
334  "public class "+fileName+"Controller {"+System.lineSeparator()+
335  " // TODO"+System.lineSeparator()+
336  "}";
337 
338  break;
339  case 3: contents =
340  "package "+parsePackageName+";"+System.lineSeparator()+System.lineSeparator()+
341 
342  "import javafx.application.Application;" +System.lineSeparator()+
343  "import javafx.stage.Stage;"+System.lineSeparator()+
344  "import javafx.scene.Scene;"+System.lineSeparator()+
345  "import javafx.scene.layout.Pane;"+System.lineSeparator()+
346  "import javafx.fxml.FXMLLoader;"+System.lineSeparator()+System.lineSeparator()+System.lineSeparator()+
347 
348 
349  "/**"+System.lineSeparator()+
350  " * @author "+System.getProperty("user.name").toString()+System.lineSeparator()+
351  " * @version "+aika.get(Calendar.DAY_OF_MONTH)+"."+(aika.get(Calendar.MONTH) + 1)+"."+aika.get(Calendar.YEAR)+System.lineSeparator()+
352  " *"+System.lineSeparator()+
353  " */"+System.lineSeparator()+
354  "public class "+fileName+"Main extends Application {"+System.lineSeparator()+
355  " @Override"+System.lineSeparator()+
356  " public void start(Stage primaryStage) {"+System.lineSeparator()+
357  " try {"+System.lineSeparator()+
358  " FXMLLoader ldr = new FXMLLoader(getClass().getResource(\""+fileName+"View.fxml\"));"+System.lineSeparator()+
359  " final Pane root = ldr.load();"+System.lineSeparator()+
360  " //final "+fileName+"Controller "+fileName.toLowerCase()+"Ctrl = ("+fileName+"Controller) ldr.getController();"+System.lineSeparator()+
361  " Scene scene = new Scene(root);"+System.lineSeparator()+
362  " scene.getStylesheets().add(getClass().getResource(\""+fileName.toLowerCase()+".css\").toExternalForm());"+System.lineSeparator()+
363  " primaryStage.setScene(scene);"+System.lineSeparator()+
364  " primaryStage.setTitle(\""+alkupFileName+"\");"+System.lineSeparator()+
365  " primaryStage.show();"+System.lineSeparator()+
366  " } catch(Exception e) {"+System.lineSeparator()+
367  " e.printStackTrace();"+System.lineSeparator()+
368  " }"+System.lineSeparator()+
369  " }"+System.lineSeparator()+System.lineSeparator()+
370 
371  " /**"+System.lineSeparator()+
372  " * @param args Ei käytössä"+System.lineSeparator()+
373  " */"+System.lineSeparator()+
374  " public static void main(String[] args) {"+System.lineSeparator()+
375  " launch(args);"+System.lineSeparator()+
376  " }"+System.lineSeparator()+
377  "}"; break;
378 
379 
380  case 4:
381  contents =
382  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +System.lineSeparator()+System.lineSeparator()+
383 
384  "<?import javafx.scene.layout.BorderPane?>"+System.lineSeparator()+System.lineSeparator()+
385 
386  "<BorderPane xmlns:fx=\"http://javafx.com/fxml/1\" fx:controller=\""+parsePackageName+"."+fileName+"Controller\">"+System.lineSeparator()+
387  " <!-- TODO Add Nodes -->"+System.lineSeparator()+
388  "</BorderPane>"+System.lineSeparator();
389  break;
390  default:
391  break;
392  }
393  return new ByteArrayInputStream(contents.getBytes());
394  }
395 
396  private InputStream openFxprojektStream(IContainer cont) {
397  String contents =
398  "<?xml version=\"1.0\" encoding=\"ASCII\"?>"+System.lineSeparator()+
399  "<anttasks:AntTask xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:anttasks=\"http://org.eclipse.fx.ide.jdt/1.0\" buildDirectory=\"${project}/build\">"+System.lineSeparator()+
400  " <deploy>"+System.lineSeparator()+
401  " <application name=\""+cont.getFullPath().toString().replace("/","")+"\"/>"+System.lineSeparator()+
402  " <info/>"+System.lineSeparator()+
403  " </deploy>"+System.lineSeparator()+
404  " <signjar/>"+System.lineSeparator()+
405  "</anttasks:AntTask>"+System.lineSeparator();
406  return new ByteArrayInputStream(contents.getBytes());
407  }
408 
409  private void throwCoreException(String message) throws CoreException {
410  IStatus status =
411  new Status(IStatus.ERROR, "javaFXpackage", IStatus.OK, message, null);
412  throw new CoreException(status);
413  }
414 
415  /**
416  * We will accept the selection in the workbench to see if
417  * we can initialize from it.
418  * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
419  */
420  @Override
421  public void init(IWorkbench workbench, IStructuredSelection select) {
422  this.selection = select;
423  }
424 }