Java tutorial
/******************************************************************************* * Copyright (c) 2012, 2015 Pivotal Software, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of 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. * * Contributors: * Pivotal Software, Inc. - initial API and implementation ********************************************************************************/ package cn.dockerfoundry.ide.eclipse.server.ui.internal.editor; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.cloudfoundry.client.lib.domain.CloudService; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.forms.ManagedForm; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.progress.UIJob; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.IServerListener; import org.eclipse.wst.server.core.ServerEvent; import org.eclipse.wst.server.ui.editor.ServerEditorPart; import cn.dockerfoundry.ide.eclipse.server.core.internal.DockerFoundryPlugin; import cn.dockerfoundry.ide.eclipse.server.core.internal.DockerFoundryServer; import cn.dockerfoundry.ide.eclipse.server.core.internal.CloudServerEvent; import cn.dockerfoundry.ide.eclipse.server.core.internal.CloudServerListener; import cn.dockerfoundry.ide.eclipse.server.core.internal.DockerApplicationService; import cn.dockerfoundry.ide.eclipse.server.core.internal.ServerEventHandler; import cn.dockerfoundry.ide.eclipse.server.core.internal.client.DockerFoundryApplicationModule; import cn.dockerfoundry.ide.eclipse.server.core.internal.client.CloudRefreshEvent; import cn.dockerfoundry.ide.eclipse.server.ui.internal.DockerFoundryImages; import cn.dockerfoundry.ide.eclipse.server.ui.internal.Messages; import cn.dockerfoundry.ide.eclipse.server.ui.internal.actions.RefreshEditorAction; import cn.dockerfoundry.ide.eclipse.server.ui.internal.actions.EditorAction.EditorCloudEvent; import cn.dockerfoundry.ide.eclipse.server.ui.internal.actions.EditorAction.RefreshArea; /** * @author Terry Denney * @author Leo Dos Santos * @author Steffen Pingel * @author Christian Dupuis */ public class DockerFoundryApplicationsEditorPage extends ServerEditorPart { private DockerFoundryServer cloudServer; private ApplicationMasterDetailsBlock masterDetailsBlock; private ManagedForm mform; private ServerListener serverListener; private final List<CloudServerListener> cloudServerListeners = new ArrayList<CloudServerListener>(); private List<DockerApplicationService> services; private ScrolledForm sform; private int[] applicationMemoryChoices; private final int MAX_ERROR_MESSAGE = 100; private UIJob refreshJob; private RefreshEditorOperation currentRefreshOp; @Override public void createPartControl(Composite parent) { mform = new ManagedForm(parent); FormToolkit toolkit = getFormToolkit(parent.getDisplay()); sform = mform.getForm(); sform.getForm().setText(Messages.COMMONTXT_APPLICATIONS); toolkit.decorateFormHeading(sform.getForm()); cloudServer = (DockerFoundryServer) getServer().getOriginal().loadAdapter(DockerFoundryServer.class, null); masterDetailsBlock = new ApplicationMasterDetailsBlock(this, cloudServer); masterDetailsBlock.createContent(mform); sform.getForm().setImage(DockerFoundryImages.getImage(DockerFoundryImages.OBJ_APPLICATION)); refresh(RefreshArea.MASTER); serverListener = new ServerListener(); addCloudServerListener(serverListener); getServer().getOriginal().addServerListener(serverListener); } /** * * @param listener to be notified of Cloud server and application changes. * The editor manages the lifecycle of the listener once it is added, * including removing it when the editor is disposed. */ public void addCloudServerListener(CloudServerListener listener) { if (listener != null && !cloudServerListeners.contains(listener)) { ServerEventHandler.getDefault().addServerListener(listener); cloudServerListeners.add(listener); } } @Override public void dispose() { for (CloudServerListener listener : cloudServerListeners) { ServerEventHandler.getDefault().removeServerListener(listener); } getServer().getOriginal().removeServerListener(serverListener); if (mform != null) { mform.dispose(); mform = null; } super.dispose(); }; public DockerFoundryServer getCloudServer() { return cloudServer; } public ApplicationMasterDetailsBlock getMasterDetailsBlock() { return masterDetailsBlock; } public List<DockerApplicationService> getServices() { return services; } public int[] getApplicationMemoryChoices() { return applicationMemoryChoices; } public boolean isDisposed() { return sform.isDisposed(); } public void reflow() { mform.getForm().reflow(true); } public void refresh(RefreshArea area) { RefreshEditorAction.getRefreshAction(this, area).run(); } public void selectAndReveal(IModule module) { // Refresh the UI immediately with the cached information for the module masterDetailsBlock.refreshUI(RefreshArea.MASTER); TableViewer viewer = masterDetailsBlock.getMasterPart().getApplicationsViewer(); viewer.setSelection(new StructuredSelection(module)); // Launch a fresh operation that will update the module. As this is // longer // running, it will eventually refresh the UI via events refresh(RefreshArea.DETAIL); } @Override public void setFocus() { } public void setMessage(String message, int messageType) { String messageToDisplay = message; if (messageToDisplay == null) { sform.setMessage(null, IMessageProvider.NONE); } else { // First replace all return carriages, or new lines with spaces StringBuffer buffer = new StringBuffer(messageToDisplay); for (int i = 0; i < buffer.length(); i++) { char ch = buffer.charAt(i); if (ch == '\r' || ch == '\n') { buffer.replace(i, i + 1, " "); //$NON-NLS-1$ } } if (buffer.length() > MAX_ERROR_MESSAGE) { String endingSegment = Messages.DockerFoundryApplicationsEditorPage_TEXT_SEE_ERRORLOG; messageToDisplay = buffer.substring(0, MAX_ERROR_MESSAGE).trim() + endingSegment; DockerFoundryPlugin.logError(message); } else { messageToDisplay = buffer.toString(); } sform.setMessage(messageToDisplay, messageType); } } public void setServices(List<DockerApplicationService> services) { this.services = services; } public void setApplicationMemoryChoices(int[] applicationMemoryChoices) { this.applicationMemoryChoices = applicationMemoryChoices; } private synchronized void setRefreshOp(RefreshEditorOperation op) { this.currentRefreshOp = op; } private synchronized RefreshEditorOperation getRefreshOp() { return this.currentRefreshOp; } private class ServerListener implements CloudServerListener, IServerListener { public void serverChanged(final CloudServerEvent event) { if (event.getServer() == null) { DockerFoundryPlugin.logError( "Internal error: unable to refresh editor. No Cloud server specified in the server event."); // $NON-NLS-1$ return; } // Do not refresh if not from the same server if (!cloudServer.getServer().getId().equals(event.getServer().getServer().getId())) { return; } // Don't trigger editor refresh on instances update to avoid // multiple // refreshes as it is performed // as part of an application update operation which triggers // a separate module refresh event if (event.getType() != CloudServerEvent.EVENT_INSTANCES_UPDATED) { RefreshArea area = event instanceof EditorCloudEvent ? ((EditorCloudEvent) event).getRefreshArea() : RefreshArea.ALL; launchRefresh(new RefreshEditorOperation(event, area)); } } public void serverChanged(ServerEvent event) { // refresh when server is saved, e.g. due to add/remove of modules if (event.getKind() == ServerEvent.SERVER_CHANGE) { launchRefresh(new RefreshEditorOperation(CloudServerEvent.EVENT_SERVER_REFRESHED, RefreshArea.ALL, event.getStatus())); } } } protected void launchRefresh(RefreshEditorOperation refreshOp) { setRefreshOp(refreshOp); // Only schedule one job per editor page session, in case multiple // refresh requests are received, only the one that is currently // scheduled should execute if (refreshJob == null) { refreshJob = new UIJob(Messages.DockerFoundryApplicationsEditorPage_JOB_REFRESH) { @Override public IStatus runInUIThread(IProgressMonitor monitor) { RefreshEditorOperation op = getRefreshOp(); if (op != null) { op.run(monitor); } return Status.OK_STATUS; } }; } refreshJob.schedule(); } protected void setErrorInPage(String message) { if (message == null) { setMessage(null, IMessageProvider.NONE); } else { setMessage(message, IMessageProvider.ERROR); } } protected void setMessageInPage(IStatus status) { String message = status.getMessage(); int providerStatus = IMessageProvider.NONE; switch (status.getSeverity()) { case IStatus.INFO: providerStatus = IMessageProvider.INFORMATION; break; case IStatus.WARNING: providerStatus = IMessageProvider.WARNING; break; } setMessage(message, providerStatus); } /** * Refresh operation that should only be run in UI thread. * */ private class RefreshEditorOperation { private CloudServerEvent event; private final RefreshArea area; private final int type; private final IStatus status; public RefreshEditorOperation(CloudServerEvent event, RefreshArea area) { this.event = event; this.area = area; this.type = event.getType(); this.status = event.getStatus() != null ? event.getStatus() : Status.OK_STATUS; } public RefreshEditorOperation(int eventType, RefreshArea area, IStatus status) { this.area = area; this.type = eventType; this.status = status != null ? status : Status.OK_STATUS; } public void run(IProgressMonitor monitor) { if (isDisposed() || mform == null || mform.getForm() == null || mform.getForm().isDisposed() || masterDetailsBlock.getMasterPart().getManagedForm().getForm().isDisposed()) { return; } try { services = cloudServer.getBehaviour().getServices(monitor); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (services == null) { services = Collections.emptyList(); } setServices(services); if (event instanceof CloudRefreshEvent && (this.type == CloudServerEvent.EVENT_UPDATE_SERVICES || this.type == CloudServerEvent.EVENT_SERVER_REFRESHED) && status.getSeverity() != IStatus.ERROR) { List<DockerApplicationService> services = ((CloudRefreshEvent) event).getServices(); } Throwable error = status.getException(); // Refresh the UI before handing any errors masterDetailsBlock.refreshUI(area); // Process errors if (status.getSeverity() == IStatus.WARNING || status.getSeverity() == IStatus.INFO) { setMessageInPage(status); } else if (error != null || status.getSeverity() == IStatus.ERROR) { StatusManager.getManager().handle(status, StatusManager.LOG); setErrorInPage(status.getMessage()); } else { IModule currentModule = getMasterDetailsBlock().getCurrentModule(); // If no error is found, be sure to set null for the // message to // clear any error messages String errorMessage = null; if (currentModule != null) { DockerFoundryApplicationModule appModule = getCloudServer() .getExistingCloudModule(currentModule); if (appModule != null && appModule.getErrorMessage() != null) { errorMessage = appModule.getErrorMessage(); } } setErrorInPage(errorMessage); } } } }