Java tutorial
package com.arcusys.liferay.vaadinplugin; /* * #%L * Liferay Vaadin Plugin * %% * Copyright (C) 2010 - 2013 Vaadin Ltd. * Copyright (C) 2013 Arcusys Ltd. * %% * Licensed 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. * #L% */ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.portlet.PortletPreferences; import javax.portlet.PortletRequest; import org.joda.time.DateTime; import com.arcusys.liferay.vaadinplugin.ui.AdditionalDependenciesWindow; import com.arcusys.liferay.vaadinplugin.ui.ChangeVersionWindow; import com.arcusys.liferay.vaadinplugin.ui.DetailsWindow; import com.arcusys.liferay.vaadinplugin.ui.OutputConsole; import com.arcusys.liferay.vaadinplugin.util.ControlPanelPortletUtil; import com.arcusys.liferay.vaadinplugin.util.DownloadInfo; import com.arcusys.liferay.vaadinplugin.util.ILog; import com.arcusys.liferay.vaadinplugin.util.VaadinAddonInfo; import com.arcusys.liferay.vaadinplugin.util.VaadinVersionFetcher; import com.arcusys.liferay.vaadinplugin.util.Version; import com.arcusys.liferay.vaadinplugin.util.VersionStorage; import com.arcusys.liferay.vaadinplugin.util.WidgetsetCompilationHandler; import com.arcusys.liferay.vaadinplugin.util.WidgetsetUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.model.Portlet; import com.liferay.portal.service.PortletLocalServiceUtil; import com.liferay.portlet.PortletPreferencesFactoryUtil; import com.vaadin.data.Property; import com.vaadin.server.VaadinRequest; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.Panel; import com.vaadin.ui.ProgressIndicator; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.BaseTheme; @SuppressWarnings("serial") public class ControlPanelUI extends UI { private static final String WARNING_UPGRADE_VAADIN_VERSION_NOT_FOUND = "Could not determine the newest Vaadin version. Please download it manually from " + ControlPanelPortletUtil.VAADIN_DOWNLOAD_URL; private static final String WARNING_UPGRADE_VAADIN_VERSION = "Changing the Vaadin version will affect all the portlets. Two Vaadin versions can't be used at the same time."; private static final int POLLING_INTERVAL_MS = 500; private VersionStorage versionStorage; private VerticalLayout mainLayout; private Panel settingsPanel; private FormLayout settingsLayout; private ProgressIndicator versionUpgradeProgressIndicator; private Button changeVersionButton; private Button updateVaadinVersionButton; private HorizontalLayout vaadinVersionLayout; private Label activeWidgetsetLabel; private Label addonLibDirLabel; private Button refreshButton; private Set<VaadinAddonInfo> selectedAddons; private OptionGroup includeAddonsOptionGroup; private VerticalLayout addonsListHolder; private Label addonsNotFoundLabel; private List<File> additionalDependencies = null; private OutputConsole outputConsole; private Label additionalDependenciesLabel; private List<File> includedDependencies = null; private boolean needsUpdating; private Button additionalDependenciesButton; private Button compileWidgetsetButton; private static final Log log = LogFactoryUtil.getLog(ControlPanelUI.class); private WidgetsetCompilationHandler compiler; private Button terminateCompilationButton; private ProgressIndicator compilationProgressIndicator; private DownloadInfo newestDownloadInfo; private VaadinUpdater vaadinUpdater; private ILog outputLog; private Button detailsButton; @Override protected void init(final VaadinRequest request) { //checkResources(); newestDownloadInfo = getNewestDownloadInfo(); onRequestStart((PortletRequest) request); createUI(); outputLog = new ILog() { @Override public void log(String message) { try { getSession().getLockInstance().lock(); outputConsole.log(message); } finally { getSession().getLockInstance().unlock(); } } }; refreshAddons(); } private void createUI() { //create main layout mainLayout = new VerticalLayout(); mainLayout.setWidth("720px"); mainLayout.setSpacing(true); setContent(mainLayout); //create Setting layout settingsPanel = new Panel("Settings"); settingsLayout = new FormLayout(); settingsPanel.setContent(settingsLayout); versionUpgradeProgressIndicator = createProgressIndicator(); changeVersionButton = createChangeVersionButton(); updateVaadinVersionButton = createUpdateVaadinVersionButton(); Version vaadinNewestVersion = newestDownloadInfo.getVersion(); //add details detailsButton = createDetailsButton(); vaadinVersionLayout = createVaadinVersionLayout(vaadinNewestVersion.toString(), changeVersionButton, updateVaadinVersionButton, versionUpgradeProgressIndicator, detailsButton); settingsLayout.addComponent(vaadinVersionLayout); activeWidgetsetLabel = createActiveWidgetsetLabel(); settingsLayout.addComponent(activeWidgetsetLabel); // Add-on selection HorizontalLayout addonDirectoryLayout = createAddonDirectoryLayout(); settingsLayout.addComponent(addonDirectoryLayout); //Add-on included includeAddonsOptionGroup = createIncludeAddonsList(); addonsListHolder = createIncludeAddonsListLayout(includeAddonsOptionGroup); settingsLayout.addComponent(addonsListHolder); //addition dependencies additionalDependenciesLabel = createAdditionalDependenciesLabel(); settingsLayout.addComponent(additionalDependenciesLabel); mainLayout.addComponent(settingsPanel); additionalDependenciesButton = createAdditionalDependenciesButton(); mainLayout.addComponent(additionalDependenciesButton); //Compilation layout HorizontalLayout compilationlayout = new HorizontalLayout(); compileWidgetsetButton = createCompileWidgetsetButton(); compilationlayout.addComponent(compileWidgetsetButton); terminateCompilationButton = createTerminateCompilationButton(); compilationlayout.addComponent(terminateCompilationButton); compilationProgressIndicator = createProgressIndicator(); compilationlayout.addComponent(compilationProgressIndicator); compilationlayout.setComponentAlignment(compilationProgressIndicator, Alignment.MIDDLE_LEFT); settingsLayout.addComponent(compilationlayout); //Output console outputConsole = createOutputConsole(); mainLayout.addComponent(outputConsole); addonsNotFoundLabel = createAddonsNotFoundLabel(); } private static DownloadInfo getNewestDownloadInfo() { VaadinVersionFetcher versionFetcher = new VaadinVersionFetcher(); try { DownloadInfo latestVersion = versionFetcher.fetchLatestReleaseVersion(); if (latestVersion == null) { return new DownloadInfo(new Version("unknown"), DownloadInfo.VaadinReleaseType.release, "", new DateTime()); } else { return latestVersion; } } catch (Exception e) { log.warn(e); return new DownloadInfo(new Version("unknown"), DownloadInfo.VaadinReleaseType.release, "", new DateTime()); } } private ProgressIndicator createProgressIndicator() { ProgressIndicator progressIndicator = new ProgressIndicator(); progressIndicator.setIndeterminate(true); progressIndicator.setPollingInterval(POLLING_INTERVAL_MS); progressIndicator.setEnabled(false); progressIndicator.setVisible(false); return progressIndicator; } private Button createChangeVersionButton() { Button button = new Button("Change version"); button.setStyleName(BaseTheme.BUTTON_LINK); button.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { ChangeVersionWindow window = new ChangeVersionWindow(); addWindow(window); window.initialize(); } }); return button; } private Button createDetailsButton() { Button button = new Button("Details"); button.setStyleName(BaseTheme.BUTTON_LINK); button.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { addWindow(new DetailsWindow()); } }); return button; } private Button createUpdateVaadinVersionButton() { Button button = new Button("Upgrade"); button.setImmediate(true); button.setStyleName(BaseTheme.BUTTON_LINK); button.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { if (!newestDownloadInfo.isExists()) { Notification.show(WARNING_UPGRADE_VAADIN_VERSION_NOT_FOUND, Notification.Type.ERROR_MESSAGE); return; } outputLog.log("Location for download: " + newestDownloadInfo.getDownloadUrl()); try { addWindow(new WarningWindow(newestDownloadInfo)); } catch (Exception ex) { outputLog.log(ex.getMessage()); } } }); return button; } private HorizontalLayout createVaadinVersionLayout(String newestVersion, Button changeVersionButton, Button updateVaadinVersionButton, ProgressIndicator versionUpgradeProgressIndicator, Button detailsButton) { HorizontalLayout layout = new HorizontalLayout(); layout.setSpacing(true); layout.setCaption("Vaadin Jar Version"); Label vaadinVersionLabel = new Label(); vaadinVersionLabel.setSizeUndefined(); String version = null; try { version = ControlPanelPortletUtil.getPortalVaadinServerVersion(); } catch (FileNotFoundException e) { log.warn("vaadin-server.jar couldn't be read. file not found."); } catch (IOException e) { log.warn("vaadin-server.jar couldn't be read. ", e); } if (version == null) { try { version = ControlPanelPortletUtil.getPortalVaadin6Version(); } catch (IOException e) { log.warn("vaadin.jar couldn't be read."); } } if (version == null) { version = "could not be determined"; } vaadinVersionLabel.setValue(version); layout.addComponent(vaadinVersionLabel); if (version.startsWith("7")) { layout.addComponent(detailsButton); } layout.addComponent(changeVersionButton); Label newestVaadinVersionLabel = new Label(); newestVaadinVersionLabel.setSizeUndefined(); newestVaadinVersionLabel.setValue("(newest stable version: " + newestVersion + ")"); layout.addComponent(newestVaadinVersionLabel); if (!version.equals(newestVersion)) { layout.addComponent(updateVaadinVersionButton); } layout.addComponent(versionUpgradeProgressIndicator); return layout; } private Label createActiveWidgetsetLabel() { Label activeWidgetsetLabel = new Label(); activeWidgetsetLabel.setCaption("Active Widget Set"); String value = ControlPanelPortletUtil.getPortalWidgetset(); activeWidgetsetLabel.setValue(value); return activeWidgetsetLabel; } private HorizontalLayout createAddonDirectoryLayout() { HorizontalLayout layout = new HorizontalLayout(); layout.setSpacing(true); layout.setCaption("Add-on Directory"); addonLibDirLabel = createAddonLibDirLabel(); layout.addComponent(addonLibDirLabel); refreshButton = createRefreshButton(); layout.addComponent(refreshButton); layout.setComponentAlignment(refreshButton, Alignment.MIDDLE_LEFT); return layout; } private Label createAddonLibDirLabel() { Label addonLibDirLabel = new Label(); addonLibDirLabel.setSizeUndefined(); String value = ControlPanelPortletUtil.getPortalLibLocationPath(); addonLibDirLabel.setValue(value); return addonLibDirLabel; } private Button createRefreshButton() { Button button = new Button("[re-scan]", new Button.ClickListener() { @SuppressWarnings("unchecked") public void buttonClick(Button.ClickEvent event) { selectedAddons = (Set<VaadinAddonInfo>) includeAddonsOptionGroup.getValue(); refreshAddons(); } }); button.setStyleName(BaseTheme.BUTTON_LINK); return button; } private void refreshAddons() { final List<VaadinAddonInfo> addons = WidgetsetUtil .getAvailableWidgetSets(new File(ControlPanelPortletUtil.getPortalLibLocationPath())); includeAddonsOptionGroup.removeAllItems(); if (addons.isEmpty()) { // Replace the option group with a message if no addons addonsListHolder.removeAllComponents(); addonsListHolder.addComponent(addonsNotFoundLabel); } else { for (VaadinAddonInfo addon : addons) { includeAddonsOptionGroup.addItem(addon); } includeAddonsOptionGroup.setValue(selectedAddons); addonsListHolder.removeAllComponents(); addonsListHolder.addComponent(includeAddonsOptionGroup); } // Note: the GWT lib dir entries don't have to be excluded as they're // not included in the libs returned by getLibs(); List<File> exclude = new ArrayList<File>(); exclude.add(ControlPanelPortletUtil.getVaadinServerJarLocation()); for (VaadinAddonInfo addon : addons) { exclude.add(addon.getJarFile()); } additionalDependencies = ControlPanelPortletUtil.getLibs(exclude); } private OutputConsole createOutputConsole() { OutputConsole outputConsole = new OutputConsole("Output Console"); outputConsole.setWidth("100%"); outputConsole.setHeight("400px"); return outputConsole; } private Label createAdditionalDependenciesLabel() { Label dependencyList = new Label("", ContentMode.HTML); dependencyList.setCaption("Other Dependencies"); if (includedDependencies != null) { String value = ""; if (includedDependencies.size() > 0) { for (File file : includedDependencies) { if (!value.equals("")) { value += "<br/>"; } value += file.getName(); } } else { value = "none"; } dependencyList.setValue(value); } return dependencyList; } private OptionGroup createIncludeAddonsList() { OptionGroup includeAddonsOptionGroup = new OptionGroup(); includeAddonsOptionGroup.setMultiSelect(true); includeAddonsOptionGroup.addValueChangeListener(new Property.ValueChangeListener() { public void valueChange(Property.ValueChangeEvent event) { needsUpdating = true; } }); return includeAddonsOptionGroup; } private VerticalLayout createIncludeAddonsListLayout(OptionGroup includeAddonsOptionGroup) { VerticalLayout addonsListHolder = new VerticalLayout(); addonsListHolder.setCaption("Select Add-ons"); addonsListHolder.addComponent(includeAddonsOptionGroup); return addonsListHolder; } private Button createAdditionalDependenciesButton() { Button button = new Button("Manage Additional Dependencies", new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { showAdditionalDependenciesWindow(); } }); button.setStyleName(BaseTheme.BUTTON_LINK); return button; } private void showAdditionalDependenciesWindow() { final AdditionalDependenciesWindow additionalDependenciesWindow = new AdditionalDependenciesWindow( additionalDependencies, includedDependencies); additionalDependenciesWindow.setModal(true); additionalDependenciesWindow.addCloseListener(new Window.CloseListener() { public void windowClose(Window.CloseEvent e) { additionalDependenciesButton.setEnabled(true); updateDependencies(additionalDependenciesWindow.getAdditionalDependencies()); } }); addWindow(additionalDependenciesWindow); additionalDependenciesWindow.center(); additionalDependenciesButton.setEnabled(false); } private void updateDependencies(List<File> dependencies) { includedDependencies = dependencies; needsUpdating = true; // update the list of selected dependencies Label newDependenciesLabel = createAdditionalDependenciesLabel(); settingsLayout.replaceComponent(additionalDependenciesLabel, newDependenciesLabel); additionalDependenciesLabel = newDependenciesLabel; } private Label createAddonsNotFoundLabel() { return new Label("<i>Vaadin add-ons not found from the add-on directory</i>.", ContentMode.HTML); } private Button createCompileWidgetsetButton() { return new Button("Compile Widget Set", new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { setCompilationModeEnabled(true); outputConsole.clear(); compiler = new WidgetsetCompilationHandler(activeWidgetsetLabel.getValue(), getIncludeAddons(), includedDependencies, outputLog) { @Override public void compilationFinished() { System.out.println("Compilation has been finished successfully"); getUI().getSession().getLockInstance().lock(); outputLog.log("Compilation has been finished successfully"); try { setCompilationModeEnabled(false); } finally { getUI().getSession().getLockInstance().unlock(); } } }; ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(compiler); } }); } private void setCompilationModeEnabled(boolean enabled) { setButtonsEnabled(!enabled); compilationProgressIndicator.setEnabled(enabled); compilationProgressIndicator.setVisible(enabled); terminateCompilationButton.setVisible(enabled); } @SuppressWarnings("unchecked") private List<VaadinAddonInfo> getIncludeAddons() { List<VaadinAddonInfo> addons = new ArrayList<VaadinAddonInfo>(); for (VaadinAddonInfo addon : (Set<VaadinAddonInfo>) includeAddonsOptionGroup.getValue()) { addons.add(addon); } return addons; } private void setButtonsEnabled(boolean enabled) { refreshButton.setEnabled(enabled); includeAddonsOptionGroup.setEnabled(enabled); additionalDependenciesButton.setEnabled(enabled); compileWidgetsetButton.setEnabled(enabled); changeVersionButton.setEnabled(enabled); updateVaadinVersionButton.setEnabled(enabled); detailsButton.setEnabled(enabled); } private Button createTerminateCompilationButton() { Button button = new Button("Cancel", new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { compiler.terminate(); } }); button.setVisible(false); return button; } public void onRequestStart(PortletRequest request) { if (includedDependencies == null || selectedAddons == null) { PortletPreferences preferences = request.getPreferences(); String portletResource = ParamUtil.getString(request, "portletResource"); if (Validator.isNotNull(portletResource)) { try { preferences = PortletPreferencesFactoryUtil.getPortletSetup(request, portletResource); } catch (SystemException e) { log.warn(e); } catch (PortalException e) { log.warn(e); } } if (includedDependencies == null) { loadAdditionalDependencies(preferences); } if (selectedAddons == null) { loadSelectedAddons(preferences); } } } private void loadAdditionalDependencies(PortletPreferences preferences) { if (includedDependencies == null) { includedDependencies = new ArrayList<File>(); } String dependencies = preferences.getValue("additionalDependencies", null); if (dependencies != null) { File dir = new File(ControlPanelPortletUtil.getPortalLibLocationPath()); if (dir.exists()) { for (String fileName : dependencies.split(";")) { fileName = fileName.trim(); if (!"".equals(fileName)) { File file = new File(dir, fileName); if (file.exists()) { includedDependencies.add(file); } } } } } log.info("Additional dependencies retrieved."); } private void loadSelectedAddons(PortletPreferences preferences) { if (selectedAddons == null) { selectedAddons = new HashSet<VaadinAddonInfo>(); } String addonStrings = preferences.getValue("selectedAddons", null); if (addonStrings != null) { List<VaadinAddonInfo> allAddons = WidgetsetUtil .getAvailableWidgetSets(new File(ControlPanelPortletUtil.getPortalLibLocationPath())); for (String addonString : addonStrings.split(";")) { addonString = addonString.trim(); if (!"".equals(addonString)) { for (VaadinAddonInfo addon : allAddons) { if (addonString.equals(addon.toString())) { selectedAddons.add(addon); break; } } } } } log.info("Selected addons retrieved."); } private void downloadVaadin(DownloadInfo version) { vaadinUpdater = new VaadinUpdater(version, new VaadinUpdater.UpgradeListener() { public void updateComplete() { getSession().getLockInstance().lock(); outputLog.log("Vaadin version upgraded successfully."); outputLog.log("Don't forget to compile widgetset."); done(true); getSession().getLockInstance().unlock(); } private void done(boolean success) { getSession().getLockInstance().lock(); refreshVersionInfo(); // Stop polling versionUpgradeProgressIndicator.setEnabled(false); versionUpgradeProgressIndicator.setVisible(false); setButtonsEnabled(true); vaadinUpdater = null; getSession().getLockInstance().unlock(); } public void updateFailed(String message) { getSession().getLockInstance().lock(); outputLog.log(message); try { vaadinUpdater.restoreFromBackup(); } catch (Exception ex) { outputLog.log("ERROR: Can't restore files. Exception: " + ex.getMessage()); } done(false); getSession().getLockInstance().unlock(); } }, outputLog); versionUpgradeProgressIndicator.setEnabled(true); versionUpgradeProgressIndicator.setVisible(true); setButtonsEnabled(false); new Thread(vaadinUpdater).start(); } private class WarningWindow extends Window { public WarningWindow(final DownloadInfo version) { super("Warning!"); setModal(true); VerticalLayout layout = new VerticalLayout(); setContent(layout); layout.setSpacing(true); layout.setWidth("350px"); layout.addComponent(new Label(WARNING_UPGRADE_VAADIN_VERSION, ContentMode.HTML)); layout.addComponent(new Label( "After updating, you will need to redeploy all portlets using Vaadin. Otherwise, the portlets might fail randomly because of version conflicts.")); List<Portlet> detectedVaadinPortlets = new ArrayList<Portlet>(); List<Portlet> portlets = PortletLocalServiceUtil.getPortlets(); for (Portlet portlet : portlets) { if (isVaadinPortlet(portlet)) { detectedVaadinPortlets.add(portlet); } } if (!detectedVaadinPortlets.isEmpty()) { StringBuilder b = new StringBuilder("You seem to have at least "); b.append(detectedVaadinPortlets.size()); b.append(" portlet"); if (detectedVaadinPortlets.size() != 1) { b.append('s'); } b.append(" using Vaadin:<ul>"); for (Portlet portlet : detectedVaadinPortlets) { b.append("<li>").append(portlet.getDisplayName()).append("</li>"); } b.append("</ul>"); layout.addComponent(new Label(b.toString(), ContentMode.HTML)); } else { layout.addComponent(new Label("No portlets using Vaadin have been detected.")); } layout.addComponent( new Label("You Vaadin portlet might not be detected if it uses a custom Portlet class.")); HorizontalLayout buttonLayout = new HorizontalLayout(); buttonLayout.setSpacing(true); Button buttonUpgrade = new Button("Change version"); buttonUpgrade.setImmediate(true); buttonUpgrade.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { close(); downloadVaadin(version); } }); buttonLayout.addComponent(buttonUpgrade); Button buttonCancel = new Button("Cancel"); buttonCancel.setImmediate(true); buttonCancel.addClickListener(new Button.ClickListener() { public void buttonClick(Button.ClickEvent event) { close(); } }); buttonLayout.addComponent(buttonCancel); layout.addComponent(buttonLayout); } private boolean isVaadinPortlet(Portlet portlet) { if (portlet == null) return false; if (isVaadin6Portlet(portlet)) return true; if (isVaadin7Portlet(portlet)) return true; Map<String, String> initParams = portlet.getInitParams(); return initParams.containsKey("application"); } private boolean isVaadin6Portlet(Portlet portlet) { String portletClass = portlet.getPortletClass(); return portletClass.startsWith("com.vaadin.terminal.gwt.server"); } private boolean isVaadin7Portlet(Portlet portlet) { String portletClass = portlet.getPortletClass(); return portletClass.startsWith("com.vaadin.server.VaadinPortlet"); } } public void showWarningWindow(DownloadInfo version) { addWindow(new WarningWindow(version)); } private void refreshVersionInfo() { HorizontalLayout newVersionLayout = createVaadinVersionLayout(newestDownloadInfo.getVersion().toString(), changeVersionButton, updateVaadinVersionButton, versionUpgradeProgressIndicator, detailsButton); settingsLayout.replaceComponent(vaadinVersionLayout, newVersionLayout); vaadinVersionLayout = newVersionLayout; } public VersionStorage getVersionStorage() { if (versionStorage == null) versionStorage = new VersionStorage(); return versionStorage; } }