/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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. * *******************************************************************************/ package com.liferay.ide.project.ui.upgrade.animated; import com.liferay.blade.api.Problem; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.project.core.upgrade.FileProblems; import com.liferay.ide.project.core.upgrade.UpgradeAssistantSettingsUtil; import com.liferay.ide.project.ui.ProjectUI; import com.liferay.ide.project.ui.migration.AutoCorrectAction; import com.liferay.ide.project.ui.migration.AutoCorrectAllAction; import com.liferay.ide.project.ui.migration.IgnoreAction; import com.liferay.ide.project.ui.migration.IgnoreAlwaysAction; import com.liferay.ide.project.ui.migration.MarkDoneAction; import com.liferay.ide.project.ui.migration.MarkUndoneAction; import com.liferay.ide.project.ui.migration.MigrationContentProvider; import com.liferay.ide.project.ui.migration.MigrationLabelProvider; import com.liferay.ide.project.ui.migration.MigrationProblemsContainer; import com.liferay.ide.project.ui.migration.MigrationUtil; import com.liferay.ide.project.ui.migration.MigratorComparator; import com.liferay.ide.project.ui.migration.ProblemsContainer; import com.liferay.ide.project.ui.migration.RemoveAction; import com.liferay.ide.project.ui.migration.RunMigrationToolAction; import com.liferay.ide.project.ui.pref.MigrationProblemPreferencePage; import com.liferay.ide.ui.util.SWTUtil; import com.liferay.ide.ui.util.UIUtil; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CheckboxCellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IViewPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PreferencesUtil; /** * @author Andy Wu * @author Simon Jiang * @author Lovett Li * @author Terry Jia */ public class FindBreakingChangesPage extends Page implements IDoubleClickListener { public static final String ID = "com.liferay.ide.project.ui.findBreakingChangesPage"; private static final Image IMAGE_CHECKED = ProjectUI.getDefault().getImageRegistry().get( ProjectUI.CHECKED_IMAGE_ID ); private static final Image IMAGE_UNCHECKED = ProjectUI.getDefault().getImageRegistry().get( ProjectUI.UNCHECKED_IMAGE_ID ); public static boolean showAll = false; private boolean isBrowserMaximized = false; MigrationContentProvider migrationContentProvider; private SashForm _sashForm; private Browser _browser; private TableViewer _problemsViewer; private MigratorComparator _comparator; private TreeViewer _treeViewer; public FindBreakingChangesPage( Composite parent, int style, LiferayUpgradeDataModel dataModel ) { super( parent, style, dataModel, FINDBREACKINGCHANGES_PAGE_ID, true ); final Composite findBreakingchangesContainer = SWTUtil.createComposite( this, 2, 1, GridData.FILL_BOTH, 0, 0 ); _sashForm = new SashForm( findBreakingchangesContainer, SWT.HORIZONTAL | SWT.H_SCROLL ); _sashForm.setLayoutData( new GridData( GridData.FILL_BOTH ) ); SashForm nestedSashForm = new SashForm( _sashForm, SWT.VERTICAL | SWT.H_SCROLL ); nestedSashForm.setLayoutData( new GridData( GridData.FILL_BOTH ) ); GridData treeData = new GridData( GridData.FILL_BOTH ); treeData.minimumWidth = 200; treeData.heightHint = 200; _treeViewer = new TreeViewer( nestedSashForm ); _treeViewer.getTree().setLayoutData( treeData ); migrationContentProvider = new MigrationContentProvider(); _treeViewer.setContentProvider( migrationContentProvider ); ILabelDecorator decorator = PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator(); _treeViewer.setLabelProvider( new DecoratingLabelProvider( new MigrationLabelProvider(), decorator ) ); _treeViewer.setInput( getInitialInput() ); MenuManager menuMgr = new MenuManager(); IAction removeAction = new RemoveAction( _treeViewer ); menuMgr.add( removeAction ); Menu menu = menuMgr.createContextMenu( _treeViewer.getTree() ); _treeViewer.getTree().setMenu( menu ); _treeViewer.expandAll(); createTableView( nestedSashForm ); _browser = new Browser( _sashForm, SWT.BORDER ); _browser.setLayoutData( new GridData( GridData.FILL_BOTH ) ); _treeViewer.addSelectionChangedListener( new ISelectionChangedListener() { @Override public void selectionChanged( SelectionChangedEvent event ) { List<Problem> problems = null; if( showAll ) { problems = MigrationUtil.getProblemsFromTreeNode( event.getSelection() ); } else { problems = MigrationUtil.getCurrentProblemsFromTreeNode( event.getSelection() ); } if( problems != null && problems.size() > 0 ) { _problemsViewer.setInput( problems.toArray() ); _problemsViewer.setSelection( new StructuredSelection( problems.get( 0 ) ) ); } else { _problemsViewer.setInput( null ); } } } ); _problemsViewer.addSelectionChangedListener( new ISelectionChangedListener() { public void selectionChanged( final SelectionChangedEvent event ) { UIUtil.async( new Runnable() { public void run() { updateForm( event ); } }, 50 ); } } ); _treeViewer.addDoubleClickListener( new IDoubleClickListener() { @Override public void doubleClick( DoubleClickEvent event ) { if( event.getSelection() instanceof IStructuredSelection ) { final IStructuredSelection ss = (IStructuredSelection) event.getSelection(); Object element = ss.getFirstElement(); if( element instanceof FileProblems ) { MigrationUtil.openEditor( (FileProblems) element ); } } } } ); Composite buttonContainer = new Composite( findBreakingchangesContainer, SWT.NONE ); GridLayout buttonContainerLayout = new GridLayout( 1, false ); buttonContainerLayout.marginHeight = 0; buttonContainerLayout.marginWidth = 0; buttonContainer.setLayout( buttonContainerLayout ); buttonContainer.setLayoutData( new GridData( SWT.FILL, SWT.TOP, false, false, 1, 1 ) ); Button findbreakingchangesButton = new Button( buttonContainer, SWT.NONE ); findbreakingchangesButton.setImage( getImage( "migration-tasks.png" ) ); findbreakingchangesButton.setToolTipText( "Find Breaking Changes" ); findbreakingchangesButton.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { IViewPart view = UIUtil.findView( UpgradeView.ID ); new RunMigrationToolAction( "Run Migration Tool", view.getViewSite().getShell() ).run(); } } ); Button correctAllImportIssuesButton = new Button( buttonContainer, SWT.NONE ); correctAllImportIssuesButton.setImage( getImage( "bandaid.gif" ) ); correctAllImportIssuesButton.setToolTipText( "Automatically Correct Problems" ); correctAllImportIssuesButton.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { new AutoCorrectAllAction( getInitialInput() ).run(); } } ); Button expendAll = new Button( buttonContainer, SWT.NONE ); expendAll.setImage( getImage( "expandall.gif" ) ); expendAll.setToolTipText( "Expand All" ); expendAll.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { _treeViewer.expandAll(); } } ); Button collapseAll = new Button( buttonContainer, SWT.NONE ); Image collapseAllImage = PlatformUI.getWorkbench().getSharedImages().getImage( ISharedImages.IMG_ELCL_COLLAPSEALL ); collapseAll.setImage( collapseAllImage ); collapseAll.setToolTipText( "Collapse All" ); collapseAll.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { _treeViewer.collapseAll(); } } ); Button openIgnoredList = new Button( buttonContainer, SWT.NONE ); openIgnoredList.setImage( getImage( "properties.png" ) ); openIgnoredList.setToolTipText( "Open Ignored List" ); openIgnoredList.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( parent.getShell(), MigrationProblemPreferencePage.ID, null, null ); dialog.open(); } } ); Button hideTree = new Button( buttonContainer, SWT.TOGGLE ); hideTree.setImage( getImage( "hide_tree.png" ) ); hideTree.setToolTipText( "Hide Tree" ); hideTree.addListener( SWT.Selection, new Listener() { @Override public void handleEvent( Event event ) { isBrowserMaximized = !isBrowserMaximized; _sashForm.setMaximizedControl( isBrowserMaximized ? _browser : null ); } } ); _sashForm.setWeights( new int[] { 2, 3 } ); } private void createColumns( final TableViewer _problemsViewer ) { final String[] titles = { "Resolved", "Line", "Problem" }; final int[] bounds = { 65, 55, 200 }; TableViewerColumn col = createTableViewerColumn( titles[0], bounds[0], _problemsViewer ); col.setEditingSupport( new EditingSupport( _problemsViewer ) { @Override protected boolean canEdit( Object element ) { return true; } @Override protected CellEditor getCellEditor( Object element ) { return new CheckboxCellEditor( _problemsViewer.getTable() ); } @Override protected Object getValue( Object element ) { return ( (Problem) element ).getStatus() == Problem.STATUS_RESOLVED; } @Override protected void setValue( Object element, Object value ) { if( value == Boolean.TRUE ) { new MarkDoneAction().run( (Problem) element, _problemsViewer ); } else { new MarkUndoneAction().run( (Problem) element, _problemsViewer ); } } } ); col.setLabelProvider( new ColumnLabelProvider() { @Override public Image getImage( Object element ) { Problem p = (Problem) element; if( p.getStatus() == Problem.STATUS_RESOLVED ) { return IMAGE_CHECKED; } else { return IMAGE_UNCHECKED; } } public String getText( Object element ) { return null; } } ); col = createTableViewerColumn( titles[1], bounds[1], _problemsViewer ); col.setLabelProvider( new ColumnLabelProvider() { @Override public String getText( Object element ) { Problem p = (Problem) element; return p.lineNumber > -1 ? ( p.lineNumber + "" ) : ""; } } ); col = createTableViewerColumn( titles[2], bounds[2], _problemsViewer ); col.setLabelProvider( new ColumnLabelProvider() { @Override public String getText( Object element ) { Problem p = (Problem) element; return p.title; } @Override public void update( ViewerCell cell ) { super.update( cell ); Table table = _problemsViewer.getTable(); table.getColumn( 2 ).pack(); } } ); } public void createTableView( Composite container ) { GridData gridData = new GridData( GridData.FILL_BOTH ); gridData.minimumWidth = 200; gridData.minimumHeight = 200; _problemsViewer = new TableViewer( container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER ); _problemsViewer.getTable().setLayoutData( gridData ); createColumns( _problemsViewer ); final Table table = _problemsViewer.getTable(); table.setHeaderVisible( true ); _problemsViewer.setContentProvider( ArrayContentProvider.getInstance() ); _problemsViewer.setComparer( null ); _comparator = new MigratorComparator(); _problemsViewer.setComparator( _comparator ); MenuManager menuMgr = new MenuManager(); IAction markDoneAction = new MarkDoneAction( _problemsViewer ); IAction markUndoneAction = new MarkUndoneAction( _problemsViewer ); IAction ignoreAction = new IgnoreAction( _problemsViewer ); IAction ignoreAlways = new IgnoreAlwaysAction( _problemsViewer ); IAction autoCorrectAction = new AutoCorrectAction( _problemsViewer ); menuMgr.add( markDoneAction ); menuMgr.add( markUndoneAction ); menuMgr.add( ignoreAction ); menuMgr.add( autoCorrectAction ); menuMgr.add( ignoreAlways ); Menu menu = menuMgr.createContextMenu( table ); table.setMenu( menu ); _problemsViewer.addDoubleClickListener( this ); } private TableViewerColumn createTableViewerColumn( String title, int bound, TableViewer viewer ) { final TableViewerColumn viewerColumn = new TableViewerColumn( viewer, SWT.NONE ); final TableColumn column = viewerColumn.getColumn(); column.setText( title ); column.setWidth( bound ); column.setResizable( true ); column.setMoveable( true ); column.addSelectionListener( getSelectionAdapter( column, viewer.getTable().indexOf( column ) ) ); return viewerColumn; } @Override public void doubleClick( DoubleClickEvent event ) { if( event.getSelection() instanceof IStructuredSelection ) { final IStructuredSelection ss = (IStructuredSelection) event.getSelection(); Object element = ss.getFirstElement(); if( element instanceof Problem ) { MigrationUtil.openEditor( (Problem) element ); } else if( element instanceof FileProblems ) { MigrationUtil.openEditor( (FileProblems) element ); } } } private String generateFormText( Problem problem ) { StringBuilder sb = new StringBuilder(); sb.append( "<form><p>" ); sb.append( "<b>Problem:</b> " + problem.title + "<br/><br/>" ); sb.append( "<b>Description:</b><br/>" ); sb.append( "\t" + problem.summary + "<br/><br/>" ); if( problem.getAutoCorrectContext() != null && problem.autoCorrectContext.length() > 0 ) { sb.append( "<a href='autoCorrect'>Correct this problem automatically</a><br/><br/>" ); } if( problem.html != null && problem.html.length() > 0 ) { sb.append( "<a href='html'>See documentation for how to correct this problem.</a><br/><br/>" ); } if( problem.ticket != null && problem.ticket.length() > 0 ) { sb.append( "<b>Tickets:</b> " + getLinkTags( problem.ticket ) + "<br/><br/>" ); } sb.append( "</p></form>" ); return sb.toString(); } private Image getImage( String imageName ) { Image image = ImageDescriptor.createFromURL( ProjectUI.getDefault().getBundle().getEntry( "icons/e16/" + imageName ) ).createImage(); return image; } public TableViewer getProblemsViewer() { return _problemsViewer; } public List<ProblemsContainer> getInitialInput() { List<ProblemsContainer> _problems = null; try { MigrationProblemsContainer container = UpgradeAssistantSettingsUtil.getObjectFromStore( MigrationProblemsContainer.class ); if( container != null ) { _problems = new ArrayList<>(); _problems.add( container ); } } catch( IOException e ) { e.printStackTrace(); } migrationContentProvider.setProblems( _problems ); return _problems; } private String getLinkTags( String ticketNumbers ) { String[] ticketNumberArray = ticketNumbers.split( "," ); StringBuilder sb = new StringBuilder(); for( int i = 0; i < ticketNumberArray.length; i++ ) { String ticketNumber = ticketNumberArray[i]; sb.append( "<a href='https://issues.liferay.com/browse/" ); sb.append( ticketNumber ); sb.append( "'>" ); sb.append( ticketNumber ); sb.append( "</a>" ); if( ticketNumberArray.length > 1 && i != ticketNumberArray.length - 1 ) { sb.append( "," ); } } return sb.toString(); } private SelectionAdapter getSelectionAdapter( final TableColumn column, final int index ) { return new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { _comparator.setColumn( index ); int dir = _comparator.getDirection(); _problemsViewer.getTable().setSortDirection( dir ); _problemsViewer.getTable().setSortColumn( column ); _problemsViewer.refresh(); } }; } public TreeViewer getTreeViewer() { return _treeViewer; } private void updateForm( SelectionChangedEvent event ) { final ISelection selection = event.getSelection(); final Problem problem = MigrationUtil.getProblemFromSelection( selection ); if( problem != null ) { /* * if( Platform.getOS().equals( Platform.OS_LINUX ) ) { _form.setText( generateFormText( problem ), true, * false ); } else { */ if( CoreUtil.isNullOrEmpty( problem.html ) ) { _browser.setText( generateFormText( problem ) ); } else { _browser.setText( problem.html ); } // } } else { /* * if( Platform.getOS().equals( Platform.OS_LINUX ) ) { _form.setText( "", false, false ); } else { */ _browser.setUrl( "about:blank" ); // } } } public void createSpecialDescriptor( Composite parent, int style ) { final String descriptor = "This step will help you to find breaking changes for type of java, jsp, xml and properties files. " + "It will not support to find the front-end codes( e.g., javascript, css).\n For service builder, you " + "just need to modify the changes on xxxServiceImp.java, xxxFinder.java, xxxModel.java. " + "Others will be solved in step \"Build Service\"."; String url = ""; Link link = SWTUtil.createHyperLink( this, style, descriptor, 1, url ); link.setLayoutData( new GridData( SWT.FILL, SWT.BEGINNING, true, false, 2, 1 ) ); } @Override public String getPageTitle() { return "Find Breaking Changes"; } public boolean getGridLayoutEqualWidth() { return false; } public TableViewer get_problemsViewer() { return _problemsViewer; } }