Java tutorial
/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.mantle.client.ui.xul; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.DeckPanel; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.xml.client.Document; import com.google.gwt.xml.client.XMLParser; import org.pentaho.gwt.widgets.client.utils.i18n.IResourceBundleLoadCallback; import org.pentaho.gwt.widgets.client.utils.i18n.ResourceBundle; import org.pentaho.mantle.client.commands.AbstractCommand; import org.pentaho.mantle.client.events.EventBusUtil; import org.pentaho.mantle.client.events.SolutionBrowserCloseEvent; import org.pentaho.mantle.client.events.SolutionBrowserCloseEventHandler; import org.pentaho.mantle.client.events.SolutionBrowserDeselectEvent; import org.pentaho.mantle.client.events.SolutionBrowserDeselectEventHandler; import org.pentaho.mantle.client.events.SolutionBrowserOpenEvent; import org.pentaho.mantle.client.events.SolutionBrowserOpenEventHandler; import org.pentaho.mantle.client.events.SolutionBrowserSelectEvent; import org.pentaho.mantle.client.events.SolutionBrowserSelectEventHandler; import org.pentaho.mantle.client.messages.Messages; import org.pentaho.mantle.client.objects.MantleXulOverlay; import org.pentaho.mantle.client.solutionbrowser.tabs.IFrameTabPanel; import org.pentaho.ui.xul.XulException; import org.pentaho.ui.xul.XulOverlay; import org.pentaho.ui.xul.gwt.GwtXulDomContainer; import org.pentaho.ui.xul.gwt.GwtXulRunner; import org.pentaho.ui.xul.gwt.tags.GwtTree; import org.pentaho.ui.xul.gwt.util.AsyncXulLoader; import org.pentaho.ui.xul.gwt.util.IXulLoaderCallback; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; public class MantleXul implements IXulLoaderCallback, SolutionBrowserOpenEventHandler, SolutionBrowserCloseEventHandler, SolutionBrowserSelectEventHandler, SolutionBrowserDeselectEventHandler { public static final String PROPERTIES_EXTENSION = ".properties"; //$NON-NLS-1$ public static final String SEPARATOR = "/"; //$NON-NLS-1$ private GwtXulDomContainer container; private static MantleXul instance; private SimplePanel toolbar = new SimplePanel(); private SimplePanel menubar = new SimplePanel(); private SimplePanel adminPerspective = new SimplePanel(); private DeckPanel adminContentDeck = new DeckPanel(); private MantleController controller; private ArrayList<XulOverlay> overlays = new ArrayList<XulOverlay>(); private HashSet<String> loadedOverlays = new HashSet<String>(); private MantleXul() { AsyncXulLoader.loadXulFromUrl(GWT.getModuleBaseURL() + "xul/mantle.xul", GWT.getModuleBaseURL() + "messages/mantleMessages", this); EventBusUtil.EVENT_BUS.addHandler(SolutionBrowserOpenEvent.TYPE, this); EventBusUtil.EVENT_BUS.addHandler(SolutionBrowserCloseEvent.TYPE, this); EventBusUtil.EVENT_BUS.addHandler(SolutionBrowserSelectEvent.TYPE, this); EventBusUtil.EVENT_BUS.addHandler(SolutionBrowserDeselectEvent.TYPE, this); } public static MantleXul getInstance() { if (instance == null) { instance = new MantleXul(); } return instance; } /** * Callback method for the MantleXulLoader. This is called when the Xul file has been processed. * * @param runner * GwtXulRunner instance ready for event handlers and initializing. */ public void xulLoaded(GwtXulRunner runner) { // handlers need to be wrapped generically in GWT, create one and pass it our reference. // instantiate our Model and Controller controller = new MantleController(new MantleModel(this)); // Add handler to container container = (GwtXulDomContainer) runner.getXulDomContainers().get(0); container.addEventHandler(controller); try { runner.initialize(); } catch (XulException e) { Window.alert("Error initializing XUL runner: " + e.getMessage()); //$NON-NLS-1$ e.printStackTrace(); return; } // Get the toolbar from the XUL doc Widget bar = (Widget) container.getDocumentRoot().getElementById("mainToolbarWrapper").getManagedObject(); //$NON-NLS-1$ Widget xultoolbar = (Widget) container.getDocumentRoot().getElementById("mainToolbar").getManagedObject(); //$NON-NLS-1$ xultoolbar.getElement().removeClassName("toolbar"); toolbar.setStylePrimaryName("mainToolbar-Wrapper"); toolbar.setWidget(bar); // Get the menubar from the XUL doc Widget menu = (Widget) container.getDocumentRoot().getElementById("mainMenubar").getManagedObject(); //$NON-NLS-1$ menubar.setWidget(menu); // check based on user permissions final String moduleBaseURL = GWT.getModuleBaseURL(); final String moduleName = GWT.getModuleName(); final String contextURL = moduleBaseURL.substring(0, moduleBaseURL.lastIndexOf(moduleName)); final String url = contextURL + "api/repo/files/canCreate"; //$NON-NLS-1$ RequestBuilder executableTypesRequestBuilder = new RequestBuilder(RequestBuilder.GET, url); executableTypesRequestBuilder.setHeader("accept", "text/plain"); executableTypesRequestBuilder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); try { executableTypesRequestBuilder.sendRequest(null, new RequestCallback() { public void onError(Request request, Throwable exception) { // showError(exception); } public void onResponseReceived(Request request, Response response) { if (response.getStatusCode() == Response.SC_OK) { Boolean visible = new Boolean(response.getText()); controller.setMenuBarEnabled("newmenu", visible); controller.setToolBarButtonEnabled("newButton", visible); } } }); } catch (RequestException e) { // showError(e); } // get the admin perspective from the XUL doc Widget admin = (Widget) container.getDocumentRoot().getElementById("adminPerspective").getManagedObject(); //$NON-NLS-1$ admin.setStyleName("admin-perspective"); admin.getElement().getStyle().clearHeight(); admin.getElement().getStyle().clearWidth(); adminPerspective.setWidget(admin); Panel adminContentPanel = (Panel) container.getDocumentRoot().getElementById("adminContentPanel") .getManagedObject(); adminContentPanel.add(adminContentDeck); adminContentDeck.setHeight("100%"); adminContentDeck.getElement().getStyle().setProperty("height", "100%"); fetchPluginOverlays(); } public void customizeAdminStyle() { Timer t = new Timer() { public void run() { if (container != null) { cancel(); // call this method when Elements are added to DOM GwtTree adminCatTree = (GwtTree) container.getDocumentRoot().getElementById("adminCatTree"); adminCatTree.getTree().removeStyleName("gwt-Tree"); Panel adminContentPanel = (Panel) container.getDocumentRoot() .getElementById("adminContentPanel").getManagedObject(); adminContentPanel.setWidth("100%"); for (int i = 0; i < adminCatTree.getTree().getItemCount(); i++) { TreeItem treeItem = adminCatTree.getTree().getItem(i); Element e = treeItem.getElement(); e.getStyle().clearPadding(); e.addClassName("adminCatTreeItem"); if (i == adminCatTree.getTree().getItemCount() - 1) { e.addClassName("adminCatTreeItemLast"); } } MantleXul.this.selectAdminCatTreeTreeItem( Messages.getString("manageUsersAndRoles").replaceAll("&", "&")); } } }; t.scheduleRepeating(250); } public void configureAdminCatTree() { String serviceUrl = GWT.getHostPageBaseURL() + "api/ldap/config/getAttributeValues"; RequestBuilder executableTypesRequestBuilder = new RequestBuilder(RequestBuilder.GET, serviceUrl); executableTypesRequestBuilder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); try { executableTypesRequestBuilder.sendRequest(null, new RequestCallback() { public void onError(Request request, Throwable exception) { } public void onResponseReceived(Request request, Response response) { String securityProvider = response.getText(); enableUsersRolesTreeItem(securityProvider.contains("DB_BASED_AUTHENTICATION")); } }); } catch (RequestException e) { //ignored } } public void enableUsersRolesTreeItem(final boolean enabled) { Timer t = new Timer() { public void run() { if (container != null) { cancel(); String usersRolesLabel = Messages.getString("users") + "/" + Messages.getString("roles"); GwtTree adminCatTree = (GwtTree) container.getDocumentRoot().getElementById("adminCatTree"); TreeItem usersRolesTreeItem = null; Tree adminTree = adminCatTree.getTree(); Iterator<TreeItem> adminTreeItr = adminTree.treeItemIterator(); while (adminTreeItr.hasNext()) { usersRolesTreeItem = adminTreeItr.next(); if (usersRolesTreeItem.getText().equals(usersRolesLabel)) { usersRolesTreeItem.setVisible(enabled); break; } } } } }; t.scheduleRepeating(250); } public void selectAdminCatTreeTreeItem(final String treeLabel) { GwtTree adminCatTree = (GwtTree) container.getDocumentRoot().getElementById("adminCatTree"); Tree adminTree = adminCatTree.getTree(); adminTree.setSelectedItem(null, true); Iterator<TreeItem> adminTreeItr = adminTree.treeItemIterator(); while (adminTreeItr.hasNext()) { TreeItem treeItem = adminTreeItr.next(); if (treeItem.getText().equals(treeLabel)) { adminTree.setSelectedItem(treeItem, true); break; } } } public DeckPanel getAdminContentDeck() { return adminContentDeck; } public Widget getToolbar() { return toolbar; } public Widget getMenubar() { return menubar; } public Widget getAdminPerspective() { return adminPerspective; } private void fetchPluginOverlays() { AbstractCommand cmd = new AbstractCommand() { protected void performOperation(boolean feedback) { performOperation(); } protected void performOperation() { final String url = GWT.getHostPageBaseURL() + "api/plugin-manager/overlays"; //$NON-NLS-1$ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); builder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); builder.setHeader("accept", "application/json"); try { builder.sendRequest(null, new RequestCallback() { public void onError(Request request, Throwable exception) { Window.alert(exception.getMessage()); } public void onResponseReceived(Request request, Response response) { JsArray<JsXulOverlay> jsoverlays = JsXulOverlay .parseJson(JsonUtils.escapeJsonForEval(response.getText())); ArrayList<XulOverlay> overlays = new ArrayList<XulOverlay>(); for (int i = 0; i < jsoverlays.length(); i++) { JsXulOverlay o = jsoverlays.get(i); MantleXulOverlay overlay; overlay = new MantleXulOverlay(o.getId(), o.getOverlayUri(), o.getSource(), o.getResourceBundleUri(), Integer.parseInt(o.getPriority())); overlays.add(overlay); } MantleXul.this.addOverlays(overlays); final String url = GWT.getHostPageBaseURL() + "plugin/data-access/api/permissions/hasDataAccess"; //$NON-NLS-1$ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); builder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); builder.setHeader("accept", "application/json"); try { builder.sendRequest(null, new RequestCallback() { public void onError(Request request, Throwable exception) { Window.alert(exception.getMessage()); } public void onResponseReceived(Request request, Response response) { if (response.getText().equals("true")) { controller.loadOverlay("dataaccess"); } } }); } catch (RequestException e) { // showError(e); } } }); } catch (RequestException e) { // showError(e); } } }; cmd.execute(); } public void overlayLoaded() { } /** * Class to compare Overlays using their priority attribute */ private class OverlayPriority implements Comparator<XulOverlay> { @Override public int compare(XulOverlay o1, XulOverlay o2) { int value = 0; if (o1 != null && o2 != null) { if (o1.getPriority() > o2.getPriority()) { value = 1; } else if (o1.getPriority() < o2.getPriority()) { value = -1; } } else if (o1 == null && o2 != null) { value = -1; } else if (o2 == null && o1 != null) { value = 1; } return value; } } /** * Class to compare Overlays using their priority attribute */ private class OverlayLoader { private final List<XulOverlay> overlays; public OverlayLoader(List<XulOverlay> overlays) { this.overlays = new ArrayList<XulOverlay>(overlays); } public void loadOverlays() { loadOverlays(0); } private void loadOverlays(final int index) { if (index < overlays.size()) { final XulOverlay overlayToLoad = overlays.get(index); final String id = overlayToLoad.getId(); if (loadedOverlays.contains(id)) { // already loaded - skip this one and load the next OverlayLoader.this.loadOverlays(index + 1); } else { loadedOverlays.add(id); final boolean applyOnStart = id.startsWith("startup") || id.startsWith("sticky"); final Document doc = XMLParser.parse(overlayToLoad.getSource()); final String bundleUri = overlayToLoad.getResourceBundleUri(); String folder = ""; //$NON-NLS-1$ String baseName = bundleUri; // we have to separate the folder from the base name if (bundleUri.indexOf(SEPARATOR) > -1) { folder = bundleUri.substring(0, bundleUri.lastIndexOf(SEPARATOR) + 1); baseName = bundleUri.substring(bundleUri.lastIndexOf(SEPARATOR) + 1); } // some may put the .properties on incorrectly if (baseName.contains(PROPERTIES_EXTENSION)) { baseName = baseName.substring(0, baseName.indexOf(PROPERTIES_EXTENSION)); } // some may put the .properties on incorrectly if (baseName.contains(".properties")) { baseName = baseName.substring(0, baseName.indexOf(".properties")); } try { final ResourceBundle bundle = new ResourceBundle(); bundle.loadBundle(folder, baseName, true, new IResourceBundleLoadCallback() { public void bundleLoaded(String arg0) { try { container.loadOverlay(doc, bundle, applyOnStart); } catch (XulException e) { //ignored } finally { OverlayLoader.this.loadOverlays(index + 1); } } }); } catch (Exception e) { Window.alert("Error loading message bundle: " + e.getMessage()); //$NON-NLS-1$ e.printStackTrace(); } } } } } public void addOverlays(ArrayList<XulOverlay> overlays) { this.overlays.addAll(overlays); Collections.sort(this.overlays, new OverlayPriority()); if (this.overlays.size() > 0) { // wait for container to be loaded/ready Timer loadOverlayTimer = new Timer() { public void run() { if (container != null) { cancel(); new OverlayLoader(MantleXul.this.overlays).loadOverlays(); } } }; loadOverlayTimer.scheduleRepeating(250); } } public void applyOverlays(Set<String> overlayIds) { if (overlayIds != null && !overlayIds.isEmpty()) { for (String overlayId : overlayIds) { applyOverlay(overlayId); } } } public void applyOverlay(final String id) { if (container != null) { try { container.loadOverlay(id); } catch (XulException e) { //ignored } } else { Timer t = new Timer() { public void run() { try { if (container != null) { cancel(); container.loadOverlay(id); } } catch (XulException e) { //ignored } } }; t.scheduleRepeating(250); } } public void removeOverlays(Set<String> overlayIds) { if (overlayIds != null && !overlayIds.isEmpty()) { for (String overlayId : overlayIds) { removeOverlay(overlayId); } } } public void removeOverlay(final String id) { if (container != null) { try { container.removeOverlay(id); } catch (XulException e) { //ignored } } else { Timer t = new Timer() { public void run() { try { if (container != null) { cancel(); container.removeOverlay(id); } } catch (XulException e) { //ignored } } }; t.scheduleRepeating(250); } } public void overlayRemoved() { } public ArrayList<XulOverlay> getOverlays() { return overlays; } public void onTabOpened(SolutionBrowserOpenEvent event) { if (event.getWidget() != null) { applyOverlays(((IFrameTabPanel) event.getWidget()).getOverlayIds()); } } public void onTabSelected(SolutionBrowserSelectEvent event) { if (event.getWidget() != null) { applyOverlays(((IFrameTabPanel) event.getWidget()).getOverlayIds()); } } public void onTabClosed(SolutionBrowserCloseEvent event) { if (event.getWidget() != null) { removeOverlays(((IFrameTabPanel) event.getWidget()).getOverlayIds()); } } public void onTabDeselected(SolutionBrowserDeselectEvent event) { if (event.getWidget() != null) { removeOverlays(((IFrameTabPanel) event.getWidget()).getOverlayIds()); } } }