blob: ddd9de35a4d3eef7d40d37df5330ed2dd17eb1cb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.eclipse.ui.wizard;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.apache.click.eclipse.ClickPlugin;
import org.apache.click.eclipse.ClickUtils;
import org.apache.click.eclipse.preferences.Template;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* The wizard to create new click page.
*
* @author Naoki Takezoe
*/
public class NewClickPageWizard extends Wizard implements INewWizard {
// keys of dialog settings
public static final String SECTION_NEW_CLICK_PAGE = "NewClickPageWizard";
public static final String SHOULD_CREATE_HTML = "shouldCreateHTML";
public static final String SHOULD_CREATE_CLASS = "shouldCreateClass";
public static final String SHOULD_ADD_TO_CLICK_XML = "shouldAddToClickXML";
public static final String SUPERCLASS = "superclass";
private IStructuredSelection selection;
private NewClickPageWizardPage page;
private String initialPageName = null;
private String initialClassName = null;
private IFile[] openFiles = null;
public NewClickPageWizard() {
super();
setNeedsProgressMonitor(true);
setWindowTitle(ClickPlugin.getString("wizard.newPage.title"));
IDialogSettings settings = ClickPlugin.getDefault().getDialogSettings();
if(settings.getSection(SECTION_NEW_CLICK_PAGE)==null){
IDialogSettings section = settings.addNewSection(SECTION_NEW_CLICK_PAGE);
section.put(SHOULD_CREATE_HTML, true);
section.put(SHOULD_CREATE_CLASS, true);
section.put(SHOULD_ADD_TO_CLICK_XML, false);
section.put(SUPERCLASS, "org.apache.click.Page");
}
setDialogSettings(settings.getSection(SECTION_NEW_CLICK_PAGE));
}
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
}
public void setInitialClassName(String className){
this.initialClassName = className;
}
public void setInitialPageName(String pageName){
this.initialPageName = pageName;
}
public void addPages() {
Object element = null;
if(selection != null){
element = selection.getFirstElement();
}
page = new NewClickPageWizardPage("page1", element,
this.initialClassName, this.initialPageName);
addPage(page);
}
public boolean performFinish(){
final boolean shouldCreateHTML = page.shouldCreateHTML();
final boolean shouldCreateClass = page.shouldCreateClass();
final boolean shouldAddToClickXML = page.shouldAddToClickXML();
final String parentFolder = page.getParentFolder();
final String filename = page.getFilename();
final String sourceFolder = page.getSourceFolder();
final String packageName = page.getPackageName();
final String className = page.getClassName();
final String superClass = page.getSuperClass();
final Template template = page.getTemplate();
final IProject project = page.getProject();
IDialogSettings settings = getDialogSettings();
settings.put(SHOULD_CREATE_HTML, shouldCreateHTML);
settings.put(SHOULD_CREATE_CLASS, shouldCreateClass);
settings.put(SHOULD_ADD_TO_CLICK_XML, shouldAddToClickXML);
settings.put(SUPERCLASS, superClass);
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
try {
openFiles = doFinish(monitor, project, shouldCreateHTML, shouldCreateClass, shouldAddToClickXML,
parentFolder, filename, sourceFolder, packageName, className, superClass, template);
} catch (Exception e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
for(int i=0;i<openFiles.length;i++){
IDE.openEditor(ClickUtils.getActivePage(), openFiles[i]);
}
} catch (PartInitException e){
// TODO display the error message?
ClickPlugin.log(e);
} catch (InterruptedException e) {
// TODO display the error message?
ClickPlugin.log(e);
return false;
} catch (InvocationTargetException e) {
// TODO display the error message?
Throwable realException = e.getTargetException();
ClickPlugin.log(realException);
return false;
}
return true;
}
private IFile[] doFinish(IProgressMonitor monitor, IProject project,
boolean shouldCreateHTML,boolean shouldCreateClass, boolean shouldAddToClickXML,
String parentFolder, String filename, String sourceFolder, String packageName,
String className, String superClass, Template template) throws Exception {
List<IFile> files = new ArrayList<IFile>();
int totalTask = 0;
if(shouldCreateHTML){
totalTask++;
}
if(shouldCreateClass){
totalTask++;
}
if(shouldAddToClickXML){
totalTask++;
}
monitor.beginTask(ClickPlugin.getString("wizard.newPage.progress"), totalTask);
// Creates the HTML file
if(shouldCreateHTML){
try {
IFile file = null;
if(parentFolder.equals("")){
file = project.getFile(filename);
} else {
IFolder folder = project.getFolder(parentFolder);
// if(!folder.exists()){
// folder.create(true, true, new NullProgressMonitor());
// }
file = folder.getFile(filename);
}
if(!file.exists()){
String charset = ClickUtils.getCharset(project);
if(charset==null){
charset = file.getCharset();
}
file.create(getTemplateInputStream(template, charset), true, new NullProgressMonitor());
}
files.add(file);
} finally {
monitor.worked(1);
}
}
// Creates the page class
if(shouldCreateClass){
try {
IResource resource = project;
if(!sourceFolder.equals("")){
resource = project.getFolder(sourceFolder);
}
IJavaProject javaProject = JavaCore.create(project);
IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(resource);
IPackageFragment fragment = root.getPackageFragment(packageName);
if(!fragment.exists()){
root.createPackageFragment(packageName, true, new NullProgressMonitor());
fragment = root.getPackageFragment(packageName);
}
ICompilationUnit unit = fragment.getCompilationUnit(className+".java");
if(!unit.exists()){
IFile file = (IFile)unit.getResource();
file.create(getPageClassInputStream(template, packageName, className, superClass),
true, new NullProgressMonitor());
files.add(file);
}
} finally {
monitor.worked(1);
}
}
// Adds the page mapping to the click.xml
if(shouldAddToClickXML){
IStructuredModel model = null;
String newPath = filename;
String webAppRoot = ClickUtils.getWebAppRootFolder(project);
if(parentFolder.startsWith(webAppRoot)){
parentFolder = parentFolder.substring(webAppRoot.length()).replaceAll("^/|/$","");
if(parentFolder.length() > 0){
newPath = parentFolder + "/" + filename;
}
}
try {
IFile file = ClickUtils.getClickConfigFile(project);
IModelManager manager = StructuredModelManager.getModelManager();
model = manager.getModelForEdit(file);
IDOMDocument doc = ((IDOMModel)model).getDocument();
Element root = doc.getDocumentElement();
Element pages = null;
NodeList list = doc.getElementsByTagName(ClickPlugin.TAG_PAGES);
if(list.getLength()==0){
pages = doc.createElement(ClickPlugin.TAG_PAGES);
boolean inserted = false;
NodeList children = root.getChildNodes();
for(int i=0;i<children.getLength();i++){
Node node = children.item(i);
if(node instanceof Element){
root.insertBefore(pages, node);
inserted = true;
break;
}
}
if(!inserted){
root.appendChild(pages);
}
} else {
pages = (Element)list.item(0);
}
NodeList children = pages.getChildNodes();
boolean found = false;
String newClazz = className;
String pagesPackage = pages.getAttribute(ClickPlugin.ATTR_PACKAGE);
if(packageName.length()!=0){
if(pagesPackage==null || !packageName.equals(pagesPackage)){
newClazz = packageName + "." + className;
}
}
for(int i=0;i<children.getLength();i++){
Node node = children.item(i);
if(node instanceof Element && ((Element)node).getNodeName().equals(ClickPlugin.TAG_PAGE)){
Element page = (Element)node;
String path = page.getAttribute(ClickPlugin.ATTR_PATH);
String clazz = page.getAttribute(ClickPlugin.ATTR_CLASSNAME);
if(newPath.equals(path) && newClazz.equals(clazz)){
found = true;
break;
}
}
}
if(!found){
Element page = doc.createElement(ClickPlugin.TAG_PAGE);
page.setAttribute(ClickPlugin.ATTR_PATH, newPath);
page.setAttribute(ClickPlugin.ATTR_CLASSNAME, newClazz);
pages.appendChild(page);
}
model.save();
} finally {
if(model!=null){
model.releaseFromEdit();
}
monitor.worked(1);
}
}
return (IFile[])files.toArray(new IFile[files.size()]);
}
private InputStream getTemplateInputStream(Template template, String charset){
String source = new String(template.getHtmlTemplate());
source = source.replaceAll("\\$\\{charset\\}", charset);
return new ByteArrayInputStream(source.getBytes());
}
private InputStream getPageClassInputStream(Template template,
String packageName, String className, String superClass){
String source = new String(template.getPageClass());
source = source.replaceAll("\\$\\{package\\}", packageName);
source = source.replaceAll("\\$\\{classname\\}", className);
source = source.replaceAll("\\$\\{superclass\\}", superClass);
return new ByteArrayInputStream(source.getBytes());
}
}