package org.kie.eclipse.wizard.project; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Map.Entry; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.core.IProvisioningAgentProvider; import org.eclipse.equinox.p2.core.ProvisionException; import org.eclipse.equinox.p2.metadata.IArtifactKey; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.ITouchpointData; import org.eclipse.equinox.p2.metadata.ITouchpointInstruction; import org.eclipse.equinox.p2.metadata.expression.IMatchExpression; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.TransportException; import org.eclipse.jgit.lib.Ref; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressService; import org.kie.eclipse.Activator; import org.kie.eclipse.runtime.IRuntime; import org.kie.eclipse.utils.FileUtils; import org.osgi.framework.ServiceReference; public abstract class AbstractKieOnlineExampleProjectWizardPage extends WizardPage implements IKieOnlineExampleProjectWizardPage { private final static String DROOLS_SAMPLE_PROJECTS_REPOSITORY = "org.kie.eclipse.sampleProjectsRepository"; private final Collection<IInstallableUnit> EMPTY_IU_LIST = new ArrayList<IInstallableUnit>(); private Composite onlineExampleProjectGroup; private Composite browserGroup; private IQueryResult<IInstallableUnit> queryResult; private IUTreeViewer onlineExamplesTree; private Collection<IInstallableUnit> installableUnits; private Browser browser; private ServiceReference<?> providerRef; private String repositoryUrl; @Override public abstract String getProductId(); public AbstractKieOnlineExampleProjectWizardPage(String pageName) { super(pageName); } @Override public void createControl(Composite parent) { GridData gd; Composite composite = new Composite(parent, SWT.NULL); composite.setFont(parent.getFont()); composite.setLayout(new GridLayout(2, false)); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); Label label = new Label(composite, SWT.NONE); label.setText("Select Online Example Repository:"); final Combo repositoryCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY); gd = new GridData(GridData.END); gd.horizontalIndent = 10; repositoryCombo.setLayoutData(gd); repositoryCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = repositoryCombo.getSelectionIndex(); if (index>=0) { repositoryUrl = (String) repositoryCombo.getData(Integer.toString(index)); handleOnlineExampleProjectSelected(); } } }); fillRepositoryCombo(repositoryCombo); onlineExampleProjectGroup = new Composite(composite, SWT.NONE); onlineExampleProjectGroup.setLayout(new GridLayout()); gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); gd.horizontalSpan = 2; onlineExampleProjectGroup.setLayoutData(gd); showGroup(onlineExampleProjectGroup, false); setErrorMessage(null); setMessage(null); setControl(composite); } private void showGroup(Composite group, boolean show) { if (group!=null && !group.isDisposed()) { GridData gd = (GridData)group.getLayoutData(); gd.exclude = !show; group.setVisible(show); if (show) { // we may have to resize the shell to fit all the controls Point oldSize = getShell().getSize(); Point newSize = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); if (oldSize.x<newSize.x || oldSize.y<newSize.y) { newSize.x = Math.max(oldSize.x, newSize.x); newSize.y = Math.max(oldSize.y, newSize.y); getShell().setSize(newSize); } } group.getParent().layout(); } } private void fillRepositoryCombo(Combo repositoryCombo) { repositoryCombo.removeAll(); repositoryCombo.add("<None Selected>"); try { IConfigurationElement[] config = Platform.getExtensionRegistry() .getConfigurationElementsFor(DROOLS_SAMPLE_PROJECTS_REPOSITORY); int index = 1; for (IConfigurationElement e : config) { String id = e.getAttribute("id"); String name = e.getAttribute("name"); String product = e.getAttribute("product"); String url = e.getAttribute("url"); String gitUrl = e.getAttribute("gitUrl"); if (product==null || product.equals(getProductId())) { if (gitUrl!=null) { try { // Get all refs from this Git repository, including // branches and tags. The branch or tag name will // replace the strings "${BRACNH}" or "$TAG}" in the // url when fetching the available sample projects. Collection<Ref> refs; refs = Git.lsRemoteRepository() .setHeads(true) .setTags(true) .setRemote(gitUrl) .call(); if (refs.size()>0) { for (Ref ref : refs) { // Activator.println("Ref: " + ref.getName()); String a[] = ref.getName().split("/"); if (a.length==3) { String tagUrl = null; if ("heads".equals(a[1]) && url.contains("${BRANCH}")) { tagUrl = url.replace("${BRANCH}", a[2]); } else if ("tags".equals(a[1]) && url.contains("${TAG}")) { tagUrl = url.replace("${TAG}", a[2]); } if (tagUrl!=null) { repositoryCombo.add(name + " (" + a[2] + ")"); repositoryCombo.setData(Integer.toString(index), tagUrl); ++index; } } } } else { gitUrl = null; } } catch (InvalidRemoteException e2) { gitUrl = null; e2.printStackTrace(); } catch (TransportException e2) { gitUrl = null; e2.printStackTrace(); } catch (GitAPIException e2) { gitUrl = null; e2.printStackTrace(); } } if (gitUrl==null){ repositoryCombo.add(name); repositoryCombo.setData(Integer.toString(index), url); ++index; } } } repositoryCombo.select(0); repositoryUrl = null; } catch (Exception ex) { MessageDialog.openError(getShell(), "Error", ex.getMessage()); } } private String getRepositoryUrl() { return repositoryUrl; } private String createOnlineExampleProjectControls() { if (repositoryUrl==null) { queryResult = null; return "No Repository selected"; } final String[] status = new String[1]; IProgressService ps = PlatformUI.getWorkbench().getProgressService(); try { ps.busyCursorWhile(new IRunnableWithProgress() { @Override public void run(IProgressMonitor pm) { try { IProvisioningAgent agent = createProvisiongAgent(); IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent .getService(IMetadataRepositoryManager.SERVICE_NAME); IMetadataRepository repository = manager.loadRepository( new URI(getRepositoryUrl()), pm); queryResult = repository.query(QueryUtil.createIUAnyQuery(), pm); } catch (Exception ex) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { disposeOnlineExampleProjectControls(); } }); status[0] = ex.getMessage(); } } }); } catch (Exception e) { e.printStackTrace(); status[0] = e.getMessage(); } if (status[0]!=null) return status[0]; if (onlineExamplesTree == null) { onlineExamplesTree = new IUTreeViewer(onlineExampleProjectGroup, SWT.BORDER); onlineExamplesTree.initialize(); browserGroup = new Composite(onlineExampleProjectGroup, SWT.BORDER); browserGroup.setLayout(new GridLayout()); browserGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); browser = new Browser(browserGroup, SWT.NONE); browser.setLayoutData(new GridData(GridData.FILL_BOTH)); onlineExamplesTree.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IInstallableUnit iu = (IInstallableUnit) e.data; boolean browserLoaded = true; try { IMatchExpression<IInstallableUnit> f = iu.getFilter(); if (f!=null) { for (Object p : f.getParameters()) { // we can use this to identify the required Drools Runtime version: // for example, setting the "Architecture" field in feature.xml // (in the Overview page) to "Drools 6.0.x" produces this: // (osgi.arch=Drools 6.x) Activator.println(p); } } Activator.println("IU Properties:"); for (Entry<String, String> pe : iu.getProperties().entrySet()) { Activator.println(" "+pe.getKey()+"="+pe.getValue()); } for (ITouchpointData tp : iu.getTouchpointData()) { Activator.println("IU Touchpoints:"); for (Entry<String, ITouchpointInstruction> tpe : tp.getInstructions().entrySet()) { Activator.println(" "+tpe.getKey()+"="+tpe.getValue()); } } String text = iu.getProperty(IInstallableUnit.PROP_DESCRIPTION, "df_LT"); String url = iu.getProperty(IInstallableUnit.PROP_DESCRIPTION_URL); if (text != null && !text.isEmpty()) { browser.setText(text); } else if (testURL(url)) { browser.setUrl(url); } else { browser.setText("<html><body>No description is available for <b>" + iu.getProperty(IInstallableUnit.PROP_NAME) + "</b></body></html>"); } } catch (Exception ex) { browserLoaded = false; MessageDialog.openError(getShell(), "Error", "Cannot initialize Browser"); } showGroup(browserGroup, browserLoaded); onlineExamplesTree.getTree().pack(); onlineExampleProjectGroup.layout(); installableUnits = onlineExamplesTree.getSelectedIUs(); setPageComplete(isPageComplete()); } }); } onlineExamplesTree.setInput(queryResult); showGroup(browserGroup, false); browser.setText(""); if (onlineExamplesTree.getTree().getItemCount() == 0) { disposeOnlineExampleProjectControls(); return "No examples were found in the repository."; } return null; } private void handleOnlineExampleProjectSelected() { String error = createOnlineExampleProjectControls(); if (error==null) { showGroup(browserGroup, false); showGroup(onlineExampleProjectGroup, true); installableUnits = onlineExamplesTree.getSelectedIUs(); } else { showGroup(browserGroup, false); showGroup(onlineExampleProjectGroup, false); if (repositoryUrl!=null) { MessageDialog.openError(getShell(), "Error", NLS.bind("Unable to load online examples from\n{0}\nCause:\n{1}", getRepositoryUrl(), error) ); } installableUnits = null; } setPageComplete(isPageComplete()); } private void disposeOnlineExampleProjectControls() { if (onlineExamplesTree!=null) { if (!onlineExamplesTree.getTree().isDisposed()) onlineExamplesTree.dispose(); onlineExamplesTree = null; } if (browser!=null) { if (!browser.isDisposed()) browser.dispose(); browser = null; } } @Override public String downloadOnlineExampleProject(IProject project, IProgressMonitor monitor) { String projectName = project.getName(); try { for (IInstallableUnit iu : getInstallableUnits()) { if (projectName.equals(iu.getId())) { for (IArtifactKey k : iu.getArtifacts()) { String filename = k.getId() + "_" + k.getVersion() + ".jar"; URL url = new URL(getRepositoryUrl() + "/plugins/" + filename); java.io.File jarFile = FileUtils.downloadFile(url, monitor); FileUtils.extractJarFile(jarFile, project, monitor); // delete this temporary file jarFile.delete(); project.refreshLocal(IProject.DEPTH_INFINITE, monitor); } } } } catch (Exception e) { e.printStackTrace(); return e.getMessage(); } return null; } /** * Check if a given URL is accessible and if the page exists. * * @param urlString * @return */ private boolean testURL(String urlString) { boolean result = true; HttpURLConnection httpConnection = null; try { URL url = new URL(urlString); httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.getContent(); httpConnection.disconnect(); httpConnection = null; } catch (UnknownHostException ex) { result = false; } catch (IOException ex) { result = false; } finally { // cleanup if (httpConnection != null) httpConnection.disconnect(); } return result; } public Collection<IInstallableUnit> getInstallableUnits() { if (installableUnits==null) return EMPTY_IU_LIST; return installableUnits; } @Override public void dispose() { if (providerRef!=null) { Activator.getContext().ungetService(providerRef); providerRef = null; } super.dispose(); } private IProvisioningAgent createProvisiongAgent() throws ProvisionException { IProvisioningAgent result = null; providerRef = Activator.getContext().getServiceReference(IProvisioningAgentProvider.SERVICE_NAME); if (providerRef == null) { throw new RuntimeException("No provisioning agent provider is available"); //$NON-NLS-1$ } IProvisioningAgentProvider provider = (IProvisioningAgentProvider) Activator.getContext().getService(providerRef); if (provider == null) { throw new RuntimeException("No provisioning agent provider is available"); //$NON-NLS-1$ } // obtain agent for currently running system result = provider.createAgent(null); return result; } @Override public IRuntime getRuntime() { IRuntime effectiveRuntime = getRuntimeManager().getEffectiveRuntime(null, true); return effectiveRuntime; } @Override public Collection<IProjectDescription> getNewProjectDescriptions() { Collection<IProjectDescription> result = new ArrayList<IProjectDescription> (); IWorkspace workspace = ResourcesPlugin.getWorkspace(); for (IInstallableUnit iu : getInstallableUnits()) { String name = iu.getId(); IProject project = getProjectHandle(name); IProjectDescription description = workspace.newProjectDescription(project.getName()); result.add(description); } return result; } private IProject getProjectHandle(String name) { return ResourcesPlugin.getWorkspace().getRoot().getProject(name); } @Override public boolean isPageComplete() { return getInstallableUnits().size()>0; } @Override public IWizardPage getNextPage() { return null; } }