/* * JBoss, Home of Professional Open Source * Copyright 2008, Red Hat Middleware LLC, and others contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.savara.tools.common.generation.ui; import java.util.Collections; import java.util.Comparator; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; import org.savara.common.logging.DefaultFeedbackHandler; import org.savara.common.logging.FeedbackHandler; import org.savara.common.logging.MessageFormatter; import org.savara.contract.model.Contract; import org.savara.protocol.contract.generator.ContractGenerator; import org.savara.protocol.contract.generator.ContractGeneratorFactory; import org.savara.protocol.util.JournalProxy; import org.savara.protocol.util.ProtocolServices; import org.savara.tools.common.ArtifactType; import org.savara.tools.common.generation.Generator; import org.savara.tools.common.logging.FeedbackHandlerDialog; import org.scribble.common.resource.Content; import org.scribble.common.resource.DefaultResourceLocator; import org.scribble.common.resource.FileContent; import org.scribble.protocol.DefaultProtocolContext; import org.scribble.protocol.model.*; /** * This class provides the dialog for generating BPEL * artefacts. */ public class GenerateDialog extends org.eclipse.jface.dialogs.Dialog { private static Logger logger = Logger.getLogger(GenerateDialog.class.getName()); private IFile m_file=null; private ProtocolModel m_protocolModel=null; private ArtifactType m_artifactType=null; private java.util.List<Button> m_roleButtons=new java.util.Vector<Button>(); private java.util.List<Text> m_projectNames=new java.util.Vector<Text>(); private java.util.List<Combo> m_roleArtifactTypes=new java.util.Vector<Combo>(); private java.util.List<Role> m_roles=new java.util.Vector<Role>(); private static java.util.Map<String,Generator> m_generatorMap=new java.util.HashMap<String,Generator>(); private java.util.List<Generator> m_generators=null; static { try { // Initialize list of generators IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint point = registry.getExtensionPoint("org.savara.tools.common.generation.Generator"); if (point != null) { IExtension[] extensions = point.getExtensions(); for (int i = 0; i < extensions.length; i++) { for (int j=0; j < extensions[i].getConfigurationElements().length; j++) { if (extensions[i].getConfigurationElements()[j].getName().equals("generator")) { IConfigurationElement elem=extensions[i].getConfigurationElements()[j]; try { Object am=elem.createExecutableExtension("class"); if (am instanceof Generator) { GenerateDialog.addGenerator((Generator)am); } else { logger.severe("Failed to load generator: "+am); } } catch(Exception e) { logger.log(Level.SEVERE, "Failed to load generator", e); } } } } } } catch(Throwable t) { // Ignore classes not found, so can be used outside Eclipse } } /** * This is the constructor for the generate dialog. * * @param shell The shell */ public GenerateDialog(Shell shell, IFile file, ArtifactType artifactType) { super(shell); m_file = file; m_artifactType = artifactType; initialize(m_file); } public static void addGenerator(Generator generator) { m_generatorMap.put(generator.getName(), generator); } protected String getArtifactLabel() { if (m_artifactType == ArtifactType.ServiceContract) { return("Contract Type"); } else if (m_artifactType == ArtifactType.ServiceImplementation) { return("Service Type"); } return("Unknown"); } protected void initializeGeneratorList() { m_generators = new java.util.Vector<Generator>(); for (Generator gen : m_generatorMap.values()) { if (gen.getArtifactType() == m_artifactType) { m_generators.add(gen); } } Collections.sort(m_generators, new Comparator<Generator>() { public int compare(Generator arg0, Generator arg1) { return(arg0.getName().compareTo(arg1.getName())); } }); } /** * This method initializes the conversation model associated * with the supplied file resource. * * @param res The file */ protected void initialize(IFile res) { FeedbackHandler journal=new DefaultFeedbackHandler(); try { Content content=new FileContent(res.getRawLocation().toFile()); DefaultProtocolContext context= new DefaultProtocolContext(ProtocolServices.getParserManager(), new DefaultResourceLocator(res.getRawLocation().toFile().getParentFile())); m_protocolModel = ProtocolServices.getParserManager().parse(context, content, new JournalProxy(journal)); if (m_protocolModel == null) { logger.severe("Unable to load model"); } } catch(Exception e) { e.printStackTrace(); logger.log(Level.SEVERE, "Failed to parse model", e); } } /** * This method creates the dialog details. * * @param parent The parent control * @return The control containing the dialog components */ protected Control createDialogArea(Composite parent) { initializeGeneratorList(); Composite composite=(Composite)super.createDialogArea(parent); GridLayout layout = new GridLayout(); layout.numColumns = 1; composite.setLayout(layout); GridData gd=null; Group group=new Group(composite, SWT.H_SCROLL|SWT.V_SCROLL); gd=new GridData(); gd.horizontalAlignment = SWT.FILL; gd.horizontalSpan = 1; gd.widthHint = (m_artifactType == ArtifactType.ServiceImplementation ? 680 : 380); gd.grabExcessHorizontalSpace = true; group.setLayoutData(gd); layout = new GridLayout(); layout.numColumns = (m_artifactType == ArtifactType.ServiceImplementation ? 6 : 4); group.setLayout(layout); // Labels Label label=new Label(group, SWT.NONE); label.setText("Service Role"); gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 150; label.setLayoutData(gd); if (m_artifactType == ArtifactType.ServiceImplementation) { label = new Label(group, SWT.NONE); label.setText("Project Name"); gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 300; label.setLayoutData(gd); } label = new Label(group, SWT.NONE); label.setText(getArtifactLabel()); gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 150; label.setLayoutData(gd); if (m_protocolModel != null) { java.util.List<Role> roles=m_protocolModel.getRoles(); if (roles.size() == 0 && m_protocolModel.isLocated()) { roles.add(m_protocolModel.getProtocol().getLocatedRole()); } if (roles.size() == 0) { error(MessageFormatter.format(java.util.PropertyResourceBundle.getBundle( "org.savara.tools.common.Messages"), "SAVARA-COMMONTOOLS-00002"), null); throw new RuntimeException("Error occurred"); } ContractGenerator cg=ContractGeneratorFactory.getContractGenerator(); for (int i=0; i < roles.size(); i++) { Role role=roles.get(i); boolean f_server=true; if (cg != null) { Contract c=cg.generate(m_protocolModel.getProtocol(), null, role, new DefaultFeedbackHandler()); if (c != null && c.getInterfaces().size() == 0) { f_server = false; if (logger.isLoggable(Level.FINE)) { logger.fine("Role "+role+" is not a service"); } } } if (f_server) { m_roles.add(role); Button button=new Button(group, SWT.CHECK); button.setText(roles.get(i).getName()); button.setSelection(true); gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 195; button.setLayoutData(gd); m_roleButtons.add(button); button.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { checkStatus(); } }); if (m_artifactType == ArtifactType.ServiceImplementation) { Text projectName=new Text(group, SWT.NONE); String prjName=roles.get(i).getName(); // Check whether project name contains any invalid // characters prjName = checkProjectName(prjName); if (m_protocolModel.getProtocol() != null) { prjName = m_protocolModel.getProtocol().getName()+"-"+prjName; } projectName.setText(prjName); gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 300; projectName.setLayoutData(gd); m_projectNames.add(projectName); projectName.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { checkStatus(); } }); } Combo genType=new Combo(group, SWT.NONE|SWT.READ_ONLY); for (Generator gen : m_generators) { genType.add(gen.getName()); } if (m_generators.size() > 0) { genType.select(0); } gd = new GridData(); gd.horizontalSpan = 2; gd.widthHint = 150; genType.setLayoutData(gd); m_roleArtifactTypes.add(genType); } } } else { error(MessageFormatter.format(java.util.PropertyResourceBundle.getBundle( "org.savara.tools.common.Messages"), "SAVARA-COMMONTOOLS-00001"), null); throw new RuntimeException("Error occurred"); } Button button=new Button(group, SWT.NONE); button.setText("Check All"); gd = new GridData(); gd.horizontalSpan = 1; gd.widthHint = 100; button.setLayoutData(gd); button.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { for (int i=0; i < m_roleButtons.size(); i++) { m_roleButtons.get(i).setSelection(true); } checkStatus(); } }); button=new Button(group, SWT.NONE); button.setText("Clear All"); gd = new GridData(); gd.horizontalSpan = 1; gd.widthHint = 100; button.setLayoutData(gd); button.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { for (int i=0; i < m_roleButtons.size(); i++) { m_roleButtons.get(i).setSelection(false); } checkStatus(); } }); return(composite); } @Override protected Control createButtonBar(Composite parent) { Control ret=super.createButtonBar(parent); checkStatus(); return(ret); } @Override public int open() { try { return(super.open()); } catch(RuntimeException e) { logger.log(Level.SEVERE, "Failed to show dialog", e); return(CANCEL); } } protected void checkStatus() { int selected=0; boolean f_error=false; for (int i=0; i < m_roleButtons.size(); i++) { if (m_roleButtons.get(i).getSelection()) { selected++; if (m_artifactType == ArtifactType.ServiceImplementation) { m_projectNames.get(i).setEnabled(true); // Check project name String projectName=m_projectNames.get(i).getText(); if (isProjectNameValid(projectName) == false) { f_error = true; m_projectNames.get(i).setBackground( Display.getCurrent().getSystemColor(SWT.COLOR_RED)); } else { m_projectNames.get(i).setBackground( Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); } } m_roleArtifactTypes.get(i).setEnabled(true); } else { if (m_artifactType == ArtifactType.ServiceImplementation) { m_projectNames.get(i).setEnabled(false); m_projectNames.get(i).setBackground( Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); } m_roleArtifactTypes.get(i).setEnabled(false); } } if (f_error || selected == 0) { getButton(IDialogConstants.OK_ID).setEnabled(false); } else { getButton(IDialogConstants.OK_ID).setEnabled(true); } } protected String checkProjectName(String name) { String ret=name; if (ret.indexOf(java.io.File.separatorChar) != -1) { ret = ret.replace(java.io.File.separatorChar, '_'); } return(ret); } protected boolean isProjectNameValid(String name) { boolean ret=true; if (name == null || name.trim().length() == 0) { ret = false; } else if (m_file.getWorkspace().getRoot().getProject(name).exists()) { ret = false; } else { for (int i=0; ret && i < name.length(); i++) { if (i == 0) { ret = Character.isJavaIdentifierStart(name.charAt(i)); } else if ("-.".indexOf(name.charAt(i)) != -1) { ret = true; } else { ret = Character.isJavaIdentifierPart(name.charAt(i)); } } } return(ret); } /** * The ok button has been pressed. */ public void okPressed() { BusyIndicator.showWhile(Display.getCurrent(), new Runnable() { public void run() { try { //Display.getCurrent().sleep(); FeedbackHandlerDialog journal=new FeedbackHandlerDialog(Display.getCurrent().getActiveShell()); for (int i=0; i < m_roles.size(); i++) { if (m_roleButtons.get(i).getSelection()) { // Get generator Combo combo=m_roleArtifactTypes.get(i); int index=combo.getSelectionIndex(); if (index >= 0) { Generator generator=m_generators.get(index); String projectName=null; if (m_projectNames.size() > 0) { projectName = m_projectNames.get(i).getText(); } generator.generate(m_protocolModel, m_roles.get(i), projectName, m_file, journal); } } } journal.show(); } catch(Throwable e) { e.printStackTrace(); error(MessageFormatter.format(java.util.PropertyResourceBundle.getBundle( "org.savara.tools.common.Messages"), "SAVARA-COMMONTOOLS-00003"), e); } } }); super.okPressed(); } /** * This method is used to report an error. * * @param mesg The error message * @param ex The exception */ public void error(String mesg, Throwable ex) { org.savara.tools.common.osgi.Activator.logError(mesg, ex); MessageBox mbox=new MessageBox(getShell(), SWT.ICON_ERROR|SWT.OK); mbox.setMessage(mesg); mbox.open(); logger.log(Level.SEVERE, mesg, ex); } }