/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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 * * Contributors: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.coconut.description.browse.views; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Observable; import java.util.Observer; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchPage; import org.eclipse.ui.part.ViewPart; import org.reuseware.coconut.description.BrowserState; import org.reuseware.coconut.description.Facet; import org.reuseware.coconut.description.FacetType; import org.reuseware.coconut.description.FacetTypeDecorator; import org.reuseware.coconut.description.FacetValue; import org.reuseware.coconut.description.FacetValueDecorator; import org.reuseware.coconut.description.GUIState; import org.reuseware.coconut.description.browse.BrowserStateManager; import org.reuseware.coconut.description.browse.MainBrowserManager; import org.reuseware.coconut.description.browse.util.DynamicDecorationManager; import org.reuseware.coconut.description.classify.DecorationManager; import org.reuseware.coconut.description.classify.DescriptionManager; import org.reuseware.coconut.description.classify.views.facet.FacetView; import org.reuseware.coconut.description.classify.views.facet.FacetViewUtil; @SuppressWarnings("restriction") public class FacetViewsController implements Observer, IPartListener { private WorkbenchPage page; private List<FacetView> shownViews; private List<Integer> freePlaceholders; private FacetView closedView; private ViewPart swapView; private LinkedList<FacetView> badViews; private static final String DEFAULT_PLACEHOLDER = "5"; public FacetViewsController(BrowserStateManager stateManager) { this.page = (WorkbenchPage) PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getActivePage(); this.shownViews = new LinkedList<FacetView>(); this.freePlaceholders = new LinkedList<Integer>(); iniFreePlaceholders(); showPresentedFacets(); } public void unregisterListeners() { for (FacetView view : shownViews) { view.getSite().getPage().removePartListener(this); } } /** * Either refreshes the <code>FacetView</code>'s content or delets some * shown views if they show <code>FacetType</code>s which are not in the * <code>BrowserState</code> any more. */ public void clean() { // update list of shown views // FacetView facetView; // List<FacetTypeDecorator> presented = MainBrowserManager.getInstance() // .getBrowserStateManager().getState().getPresentedFacets(); // for (IViewPart iView : page.getViews()) { // if (!(iView instanceof FacetView)) // continue; // facetView = (FacetView) iView; // // // check whether facet view shows a facet stored in browser state // if (presented == null || !presented.contains(facetView.getContext())) { // swapView = facetView; // Runnable r = new Runnable() { // public void run() { // swapView.getSite().getPage().hideView(swapView); // } // }; // facetView.getSite().getShell().getDisplay().asyncExec(r); // } else // shownViews.add(facetView); // } // clean all shown views FacetTypeDecorator context; for (FacetView view : shownViews) { context = view.getContext(); System.out.println(); System.out.println("clean: " + context.getDecoratee().getName()); // check whether all valueCounts are 0 boolean update = true; for (FacetValueDecorator vDecor : context.getValues()) { update &= vDecor.getValueCount() == 0; if (!update) break; } // update context if needed if (update) { System.out.println("sauber!"); context = MainBrowserManager.getInstance().update(context); } // clean the view view.clean(context); } } private void iniFreePlaceholders() { freePlaceholders.clear(); // default number of facet views is 6 (0-5) for (int i = 0; i < 6; i++) freePlaceholders.add(i); } public void showPresentedFacets() { BrowserState state = MainBrowserManager.getInstance().getBrowserStateManager().getState(); List<FacetTypeDecorator> presentedTypes = state.getPresentedFacets(); boolean stop; for (FacetTypeDecorator typeDecor : presentedTypes) { stop = false; for (FacetView view : shownViews) { if (view.getContext().equals(typeDecor)) { stop = true; break; } } if (stop) continue; showViewFor(typeDecor, false, null); } } public void openFacetViewFor(FacetTypeDecorator decor) { if (freePlaceholders.size() == 0) { // look for the view to be replaced IViewReference[] refs = page.getViewReferences(); for (IViewReference iRef : refs) { swapView = (ViewPart) iRef.getView(true); if (swapView != null && swapView instanceof FacetView && DEFAULT_PLACEHOLDER.equals(iRef.getSecondaryId())) { // set correct view's replacement decorator ((FacetView) swapView).setReplaceContext(decor); // close this old view Runnable r = new Runnable() { public void run() { if (!isWorkbenchClosing()) swapView.getSite().getPage().hideView(swapView); shownViews.remove(swapView); } }; try { swapView.getSite().getShell().getDisplay().asyncExec(r); } catch (Exception e) { e.printStackTrace(); } return; } } } /* * else { // there might be a selection given for the new view swapFacet * = MainBrowserManager.getInstance().getTransientFacet(); swapDecor = * decor; Runnable r; if (swapFacet != null) { // open view with this * selection r = new Runnable() { * * @Override public void run() { showViewFor(swapDecor, true, * swapFacet); } }; * * // remove Facet from selected facets list BrowserState state = * MainBrowserManager.getInstance().getBrowserStateManager() * .getState(); state.getSelectedFacets().remove(swapFacet); * MainBrowserManager * .getInstance().getBrowserStateManager().setState(state); } else { r = * new Runnable() { * * @Override public void run() { showViewFor(swapDecor, true, null); } * }; } try { * PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell * ().getDisplay() .asyncExec(r); } catch (Exception e) { * e.printStackTrace(); } * * } */ } private boolean showViewFor(FacetTypeDecorator facetDecor, boolean activate, Facet editContext) { if (freePlaceholders.size() <= 0 || facetDecor == null) return false; String viewId = FacetViewUtil.getViewForType(facetDecor.getDecoratee()).VIEW_ID; IViewPart view = null; int place = freePlaceholders.get(0); // try open this view try { int mode = activate ? WorkbenchPage.VIEW_ACTIVATE : WorkbenchPage.VIEW_VISIBLE; if (page == null) return false; view = page.showView(viewId, String.valueOf(place), mode); } catch (PartInitException e) { System.err.println("Failed to show a view for: " + facetDecor.getDecoratee()); e.printStackTrace(); return false; } if (view != null && view instanceof FacetView) { // set facetView properties FacetView facetView = ((FacetView) view); facetView.browserMode = true; facetView.setContext(facetDecor, null); facetView.setZoomListener(DynamicDecorationManager.getZoomLister()); // there might be a selection context if (editContext != null) facetView.supportEdit(editContext); } else return false; view.getSite().getPage().addPartListener(this); freePlaceholders.remove(new Integer(place)); shownViews.add((FacetView) view); ((FacetView) view).place = place; return true; } private boolean isWorkbenchClosing() { WorkbenchPage page = (WorkbenchPage) PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getActivePage(); if (page == null) return true; return page.getWorkbenchWindow().getWorkbench().isClosing(); } // ******************************************************************************************** // Observer of BrowserState public void update(Observable o, Object arg) { if (!MainBrowserManager.getInstance().isBrowserPerspectivActive()) return; BrowserStateManager stateManager = MainBrowserManager.getInstance() .getBrowserStateManager(); BrowserState state = stateManager.getState(); List<FacetTypeDecorator> presentedFacets = new ArrayList<FacetTypeDecorator>(state .getPresentedFacets().size()); presentedFacets.addAll(state.getPresentedFacets()); badViews = new LinkedList<FacetView>(); List<FacetTypeDecorator> shownDecors = new LinkedList<FacetTypeDecorator>(); List<FacetView> shownViews = new ArrayList<FacetView>(this.shownViews.size()); shownViews.addAll(this.shownViews); FacetTypeDecorator context = null; boolean contains; int c = 0; // check whether all views show a FacetType from presentedFacets list for (FacetView view : shownViews) { c++; System.out.println(); System.out.println("#####"); System.out.println(c); System.out.println("#####"); System.out.println(); context = view.getContext(); contains = false; for (FacetTypeDecorator tDecor : presentedFacets) { if (DecorationManager.equal(tDecor, context)) { context = tDecor; contains = true; break; } } shownDecors.add(context); // view shows something which is not in the presented facets list // or it shows something another view is already showing if (!contains || shownDecors.indexOf(context) != shownDecors.lastIndexOf(context)) { badViews.add(view); this.shownViews.remove(view); String place = ((IViewReference) page.getReference(view)).getSecondaryId(); freePlaceholders.add(Integer.valueOf(place)); } else { // make sure view's selection is stored in presented facets list Facet select = null; List<FacetValueDecorator> selection = view.getSelection(); boolean hasSelection = selection != null && selection.size() > 0; if (hasSelection) { List<FacetValue> values = new ArrayList<FacetValue>(selection.size()); for (FacetValueDecorator vDecor : selection) values.add(vDecor.getDecoratee()); select = DescriptionManager.buildFacet(context.getDecoratee(), values); } context.setSelection(select); // make sure the view's content is up-to-date // don't update if view is active and has a selection System.out.println(); if (!state.getGuiState().equals(GUIState.UP_TO_DATE)) { boolean test = false; try { test = page.getActivePart().equals(view) && hasSelection; } catch (Exception e1) { e1.printStackTrace(); } if (test) { // do nothing } else { // recalculate context context = MainBrowserManager.getInstance().update(context); // try to refresh the view try { view.refreshContext(context, select); } catch (Exception e) { System.err.println("Disposed!"); view.setReplaceContext(context); view.setReplaceSelection(select); MainBrowserManager.getInstance().setTransientFacet(null); badViews.add(view); this.shownViews.remove(view); } } } } } shownViews.removeAll(badViews); Runnable r; for (final FacetView facetView : badViews) { // this should never happen r = new Runnable() { public void run() { System.err.println("FAILURE: NEED TO CLEAN UP FACET VIEWS"); page.hideView(facetView); } }; PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getDisplay().asyncExec( r); } // present the presented facets showPresentedFacets(); // change browser state's GUI state state.setGuiState(GUIState.UP_TO_DATE); stateManager.setState(state, true); System.out.println(); System.out.println("*********************************************************************"); for (FacetTypeDecorator fDecor : presentedFacets) { System.out.print(fDecor.getDecoratee().getName() + " = {"); if (fDecor.getSelection() != null) { for (FacetValue value : fDecor.getSelection().getValues()) { System.out.print(value.getName() + ","); } } System.out.println("}"); } System.out.println("*********************************************************************"); System.out.println(); } // ******************************************************************************************** // Listener of FacetView public void partActivated(IWorkbenchPart part) { } public void partBroughtToTop(IWorkbenchPart part) { } public void partClosed(IWorkbenchPart part) { // do nothing if workbench is closing if (isWorkbenchClosing()) return; // if this is the Fragment Browser perspective - go on if (MainBrowserManager.getInstance().isBrowserPerspectivActive()) { // make sure it's a FacetView and reacted only once if (part instanceof FacetView && !part.equals(closedView)) { FacetView facetView = (FacetView) part; // if (facetView.getContext() == null) // return; IViewReference ref = (IViewReference) part.getSite().getPage().getReference( facetView); int viewPlaceholder = Integer.parseInt(ref.getSecondaryId()); // make sure the view was created in this session // if (usedPlaceholders.contains(new Integer(viewPlaceholder))) // { if (facetView.place == viewPlaceholder) { // change BrowserState BrowserState state = MainBrowserManager.getInstance().getBrowserStateManager() .getState(); freePlaceholders.add(new Integer(viewPlaceholder)); shownViews.remove(facetView); state.getPresentedFacets().remove(facetView.getContext()); closedView = facetView; // open new facet view at old view's placeholder FacetTypeDecorator newDecor = null; // either take the replacement of the FacetView if (facetView.getReplaceContext() != null) { newDecor = facetView.getReplaceContext(); state.getAdditionalFacets().remove(newDecor); state.getPresentedFacets().add(newDecor); } // or look into the list of additional facets else { List<FacetTypeDecorator> additionalFacets = state.getAdditionalFacets(); if (additionalFacets.size() > 0) { newDecor = additionalFacets.remove(0); state.getPresentedFacets().add(newDecor); } } // there might be a selection given for the new view Facet selected = MainBrowserManager.getInstance().pullTransientFacet(); if (selected == null) selected = facetView.getReplaceSelection(); if (selected != null) { // open view with this selection showViewFor(newDecor, true, selected); // remove Facet from selected facets list state.getSelectedFacets().remove(selected); } else showViewFor(newDecor, true, null); // handle old view's state List<FacetValueDecorator> selection = facetView.getSelection(); // either save old views content if (selection != null && selection.size() > 0) { System.err.println("SELECTED!"); // build Facet to represent user's selection FacetType type = facetView.getContext().getDecoratee(); List<FacetValue> values = new ArrayList<FacetValue>(selection.size()); for (FacetValueDecorator fDecor : selection) values.add(fDecor.getDecoratee()); selected = DescriptionManager.buildFacet(type, values); // add to list of selected facets state.getSelectedFacets().add(selected); } // or mark again as additional facet else { state.getAdditionalFacets().add(facetView.getContext()); } // update model and GUI MainBrowserManager.getInstance().getBrowserStateManager().setState(state); } } } else { // the Fragment Browser perspective is closing! iniFreePlaceholders(); } } public void partDeactivated(IWorkbenchPart part) { } public void partOpened(IWorkbenchPart part) { } }