/******************************************************************************* * Copyright (c) 2012 Zend Technologies Ltd. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.zend.php.zendserver.monitor.internal.ui; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import org.apache.commons.lang.StringEscapeUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; 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.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.PlatformUI; import org.zend.core.notifications.ui.ActionType; import org.zend.core.notifications.ui.IActionListener; import org.zend.core.notifications.ui.IBody; import org.zend.core.notifications.ui.NotificationSettings; import org.zend.core.notifications.ui.dialogs.ReadMoreDialog; import org.zend.core.notifications.util.Fonts; import org.zend.php.zendserver.deployment.core.targets.TargetsManagerService; import org.zend.php.zendserver.monitor.core.EventType; import org.zend.php.zendserver.monitor.core.IEventDetails; import org.zend.php.zendserver.monitor.core.MonitorManager; import org.zend.php.zendserver.monitor.ui.ICodeTraceEditorProvider; import org.zend.sdklib.application.ZendCodeTracing; import org.zend.sdklib.internal.application.ZendConnection; import org.zend.sdklib.monitor.IZendIssue; import org.zend.sdklib.target.IZendTarget; import org.zend.webapi.core.WebApiClient; import org.zend.webapi.core.WebApiException; import org.zend.webapi.core.connection.data.EventsGroupDetails; import org.zend.webapi.core.connection.data.SystemInfo; import org.zend.webapi.core.connection.data.values.ZendServerVersion; import org.zend.webapi.internal.core.connection.exception.InvalidResponseException; /** * Implementation of {@link IBody} for Zend Server event notification. * * @author Wojciech Galanciak, 2012 * */ public class EventBody implements IBody { private static final String PROVIDER_EXTENSION = "org.zend.php.zendserver.monitor.ui.codeTracingEditor"; //$NON-NLS-1$ private IZendIssue zendIssue; private String targetId; private IEventDetails eventDetails; private int actionAvailable; private IActionListener listener; private static ICodeTraceEditorProvider editorProvider; public EventBody(String targetId, IEventDetails eventSource, IZendIssue zendIssue, int actionsAvailable) { this.zendIssue = zendIssue; this.targetId = targetId; this.eventDetails = eventSource; this.actionAvailable = actionsAvailable; } /* * (non-Javadoc) * * @see org.zend.core.notifications.ui.IBody#createContent(org.eclipse.swt. * widgets .Composite, org.zend.core.notifications.ui.NotificationSettings) */ public Composite createContent(Composite container, NotificationSettings settings) { Composite composite = createEntryComposite(container); createDescription(composite, settings); boolean isRepeat = (actionAvailable & MonitorManager.REPEAT) == MonitorManager.REPEAT; boolean isCodetrace = (actionAvailable & MonitorManager.CODE_TRACE) == MonitorManager.CODE_TRACE; boolean isSource = eventDetails.isAvailable(); int repeatAlign = SWT.LEFT; int codetraceAlign = SWT.CENTER; if (!isCodetrace) { new Label(composite, SWT.NONE); repeatAlign = SWT.CENTER; } if (!isSource) { new Label(composite, SWT.NONE); repeatAlign = repeatAlign == SWT.CENTER ? SWT.RIGHT : SWT.CENTER; codetraceAlign = SWT.RIGHT; } if (isRepeat) { createRepeatLink(composite, repeatAlign); } else { new Label(composite, SWT.NONE); } if (isCodetrace) { createTraceLink(composite, codetraceAlign); } if (isSource) { createSourceLink(composite); } return composite; } /* * (non-Javadoc) * * @see * org.zend.core.notifications.ui.IBody#addActionListener(org.zend.core. * notifications.ui.IActionListener) */ public void addActionListener(IActionListener listener) { this.listener = listener; } /* * (non-Javadoc) * * @see * org.zend.core.notifications.ui.IBody#getMenuItems(org.eclipse.swt.widgets * .Menu) */ public void addMenuItems(Menu menu) { } private void createTraceLink(Composite composite, int align) { if (getProvider() != null) { Link traceLink = createLink(composite, getLinkText(Messages.EventBody_CodetraceLink), align); traceLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { Job showCodeTraceJob = new Job(Messages.EventBody_CodetraceJobTitle) { @Override protected IStatus run(IProgressMonitor monitor) { final IZendTarget target = TargetsManagerService.INSTANCE.getTargetManager() .getTargetById(targetId); ZendConnection zendConnection = new ZendConnection() { }; WebApiClient webApiClient; try { webApiClient = zendConnection.getClient(target); SystemInfo systemInfo = webApiClient.getSystemInfo(); if (systemInfo != null && ZendServerVersion.byName("9.0.0") //$NON-NLS-1$ .compareTo(systemInfo.getVersion()) <= 0) { Display.getDefault().asyncExec(new Runnable() { public void run() { org.eclipse.swt.program.Program.launch(target.getDefaultServerURL() + ":10081/ZendServer/#!/monitoring/events/" //$NON-NLS-1$ + zendIssue.getIssue().getId()); } }); return Status.OK_STATUS; } } catch (MalformedURLException e1) { Activator.log(e1); } catch (WebApiException e) { Activator.log(e); } monitor.beginTask(Messages.EventBody_CodetraceJobTitle, IProgressMonitor.UNKNOWN); List<EventsGroupDetails> groups; try { groups = zendIssue.getGroupDetails(); } catch (InvalidResponseException e) { showMessage(Messages.EventBody_CodeTraceTitle, Messages.EventBody_CodeTraceNotSupportedMessage); return Status.OK_STATUS; } catch (WebApiException e) { showMessage(Messages.EventBody_CodeTraceTitle, Messages.EventBody_CodeTraceFailedMessage); return Status.OK_STATUS; } if (groups != null && groups.size() == 1) { EventsGroupDetails group = groups.get(0); String traceId = group.getCodeTracing(); if (traceId == null || traceId.isEmpty()) { traceId = group.getEvent().getCodeTracing(); } if (traceId != null) { ZendCodeTracing tracing = new ZendCodeTracing(targetId); File codeTrace = tracing.get(traceId); if (codeTrace != null) { getProvider().openInEditor(codeTrace.getAbsolutePath()); return Status.OK_STATUS; } } showMessage(Messages.EventBody_CodeTraceTitle, Messages.EventBody_CodetraceJobErrorMessage); } return Status.OK_STATUS; } }; showCodeTraceJob.setUser(true); showCodeTraceJob.schedule(); } }); } } private void createSourceLink(Composite composite) { Link sourceLink = createLink(composite, getLinkText(Messages.EventBody_SourceLink), SWT.RIGHT); sourceLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent selectionEvent) { OpenInEditorJob job = new OpenInEditorJob(eventDetails); job.setUser(true); job.schedule(); } }); } private void createRepeatLink(Composite composite, int align) { Link repeatLink = createLink(composite, getLinkText(Messages.EventBody_2), align); repeatLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent selectionEvent) { Job job = new RequestGeneratorJob(zendIssue); job.setUser(true); job.schedule(); if (listener != null) { listener.performAction(ActionType.HIDE); } } }); } private String getLinkText(String text) { return "<a>" + text + "</a>"; //$NON-NLS-1$ //$NON-NLS-2$ } private Link createLink(Composite parent, String text, int align) { Link link = new Link(parent, SWT.NO_FOCUS | align); link.setText(text); GridData gd = new GridData(align, SWT.FILL, true, true); link.setLayoutData(gd); return link; } private void createDescription(Composite composite, NotificationSettings settings) { Link label = new Link(composite, SWT.WRAP); label.setFont(Fonts.DEFAULT.getFont()); label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, true, true, 3, 1)); label.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); String text = zendIssue.getIssue().getGeneralDetails().getErrorString(); if (text == null || text.isEmpty()) { text = zendIssue.getIssue().getRule(); } initializeDescription(settings, label, text); } private void initializeDescription(NotificationSettings settings, Link label, String text) { final EventType type = eventDetails.getType(); if (text != null) { text = StringEscapeUtils.unescapeHtml(text); label.setText(text); } int width = Math.max(settings.getWidth(), NotificationSettings.DEFAULT_WIDTH); Point size = label.computeSize(width, SWT.DEFAULT); int height = Fonts.DEFAULT.getFont().getFontData()[0].getHeight(); if (text != null && size.y > 5 * height) { int cut = (int) (text.length() * ((double) (5 * height) / (double) size.y)); String shortText = text.substring(0, cut); int index = shortText.lastIndexOf('.'); if (index == -1) { index = shortText.lastIndexOf(' '); } shortText = shortText.substring(0, index + 1); shortText += " ... " + getLinkText(Messages.EventBody_ReadMore); //$NON-NLS-1$ label.setText(shortText); final String finalText = text; label.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { new ReadMoreDialog(org.zend.core.notifications.Activator.getDefault().getParent(), type.getRule(), finalText, type.getLink()).open(); } }); } else { if (type != null && type != EventType.UNKNOWN) { if (text != null && !text.isEmpty()) { if (!text.endsWith("\\.")) { //$NON-NLS-1$ text += '.'; } label.setText(text + ' ' + getLinkText(Messages.EventBody_ReadMore)); } else { label.setText(getLinkText(Messages.EventBody_ReadMore)); } label.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { try { PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser() .openURL(new URL(type.getLink())); } catch (Exception e) { Activator.log(e); } } }); } } } private Composite createEntryComposite(Composite container) { Composite composite = new Composite(container, SWT.NONE); GridLayout layout = new GridLayout(3, false); layout.horizontalSpacing = layout.verticalSpacing = 2; composite.setLayout(layout); return composite; } private static ICodeTraceEditorProvider getProvider() { if (editorProvider == null) { IConfigurationElement[] elements = Platform.getExtensionRegistry() .getConfigurationElementsFor(PROVIDER_EXTENSION); for (IConfigurationElement element : elements) { if ("codeTracingEditor".equals(element.getName())) { //$NON-NLS-1$ try { Object listener = element.createExecutableExtension("class"); //$NON-NLS-1$ if (listener instanceof ICodeTraceEditorProvider) { editorProvider = (ICodeTraceEditorProvider) listener; break; } } catch (CoreException e) { Activator.log(e); } } } } return editorProvider; } private void showMessage(final String title, final String message) { Display.getDefault().asyncExec(new Runnable() { public void run() { MessageDialog.openInformation(org.zend.core.notifications.Activator.getDefault().getParent(), title, message); } }); } }