/******************************************************************************* * Copyright (c) 2017 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.windup.ui.internal.rules; import static org.jboss.tools.windup.ui.WindupUIPlugin.IMG_GROOVY_RULE; import static org.jboss.tools.windup.ui.WindupUIPlugin.IMG_RULE; import static org.jboss.tools.windup.ui.WindupUIPlugin.IMG_RULE_REPO; import static org.jboss.tools.windup.ui.WindupUIPlugin.IMG_RULE_SET; import static org.jboss.tools.windup.ui.WindupUIPlugin.IMG_XML_RULE; import java.io.File; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.osgi.util.TextProcessor; import org.eclipse.swt.graphics.Image; import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.jboss.tools.windup.model.domain.WorkspaceResourceUtils; import org.jboss.tools.windup.ui.WindupUIPlugin; import org.jboss.tools.windup.ui.internal.Messages; import org.jboss.tools.windup.ui.internal.rules.RulesNode.CustomRulesNode; import org.jboss.tools.windup.ui.internal.rules.RulesNode.RulesetFileNode; import org.jboss.tools.windup.ui.internal.rules.RulesNode.SystemRulesNode; import org.jboss.tools.windup.ui.internal.rules.xml.XMLRulesetModelUtil; import org.jboss.tools.windup.windup.CustomRuleProvider; import org.jboss.windup.tooling.rules.Rule; import org.jboss.windup.tooling.rules.RuleProvider; import org.jboss.windup.tooling.rules.RuleProvider.RuleProviderType; import org.w3c.dom.Node; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @SuppressWarnings("restriction") public class RuleRepositoryContentProvider implements ITreeContentProvider, ILabelProvider, IStyledLabelProvider { private static final Image XML_RULE_PROVIDER; private static final Image GROOVY_RULE_PROVIDER; private static final Image REPOSITORY; private static final Image RULE; private static final Image RULE_SET; private Map<Node, Object> nodeMap = Maps.newHashMap(); private Map<Object, IModelStateListener> listenerMap = Maps.newHashMap(); static { ImageRegistry imageRegistry = WindupUIPlugin.getDefault().getImageRegistry(); XML_RULE_PROVIDER = imageRegistry.get(IMG_XML_RULE); GROOVY_RULE_PROVIDER = imageRegistry.get(IMG_GROOVY_RULE); REPOSITORY = imageRegistry.get(IMG_RULE_REPO); RULE = imageRegistry.get(IMG_RULE); RULE_SET = imageRegistry.get(IMG_RULE_SET); } private TreeViewer treeViewer; public RuleRepositoryContentProvider (TreeViewer treeViewer) { this.treeViewer = treeViewer; } @Override public Object[] getElements(Object inputElement) { return getChildren(inputElement); } @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof RuleRepositoryInput) { return ((RuleRepositoryInput)parentElement).getChildren(); } else if (parentElement instanceof SystemRulesNode) { return ((SystemRulesNode)parentElement).getChildren(); } else if (parentElement instanceof CustomRulesNode) { return ((CustomRulesNode)parentElement).getChildren(); } else if (parentElement instanceof RuleProvider) { RuleProvider provider = (RuleProvider)parentElement; List<Object> children = Lists.newArrayList(); children.add(new RulesetFileNode(new File(provider.getOrigin()), provider.getRuleProviderType())); List<Node> ruleNodes = XMLRulesetModelUtil.getExternalRules(provider.getOrigin()); ruleNodes.forEach(node -> nodeMap.put(node, provider)); children.addAll(ruleNodes); listen(provider); return children.stream().toArray(Object[]::new); } else if (parentElement instanceof CustomRuleProvider) { CustomRuleProvider provider = (CustomRuleProvider)parentElement; List<Object> children = Lists.newArrayList(); children.add(new RulesetFileNode(new File(provider.getLocationURI()), RuleProviderType.XML)); IFile file = WorkspaceResourceUtils.getFile(provider.getLocationURI()); List<Node> ruleNodes = XMLRulesetModelUtil.getRules(file); ruleNodes.forEach(node -> nodeMap.put(node, provider)); children.addAll(ruleNodes); listen(provider); return children.stream().toArray(Object[]::new); } return new Object[0]; } public Object getProvider(Node node) { return nodeMap.get(node); } private void listen(Object ruleProvider) { IFile file = null; if (ruleProvider instanceof CustomRuleProvider) { String locationUri = ((CustomRuleProvider)ruleProvider).getLocationURI(); file = WorkspaceResourceUtils.getFile(locationUri); } else if (ruleProvider instanceof RuleProvider) { file = XMLRulesetModelUtil.getExternallyLinkedRuleProvider((RuleProvider)ruleProvider); } IDOMModel model = XMLRulesetModelUtil.getModel(file, false); IModelStateListener listener = listenerMap.get(ruleProvider); if (listener == null) { listener = new IModelStateListener() { @Override public void modelResourceMoved(IStructuredModel oldModel, IStructuredModel newModel) { refresh(this, model, ruleProvider); } @Override public void modelResourceDeleted(IStructuredModel theModel) { refresh(this, model, ruleProvider); } @Override public void modelReinitialized(IStructuredModel structuredModel) { refresh(this, model, ruleProvider); } @Override public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { } @Override public void modelChanged(IStructuredModel theModel) { refresh(this, model, ruleProvider); } @Override public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { } @Override public void modelAboutToBeChanged(IStructuredModel model) { } }; listenerMap.put(ruleProvider, listener); } else { model.removeModelStateListener(listener); } model.addModelStateListener(listener); } private void refresh(IModelStateListener listener, IDOMModel model, Object ruleProvider) { model.removeModelStateListener(listener); listenerMap.remove(ruleProvider); if (!treeViewer.getTree().isDisposed()) { treeViewer.refresh(ruleProvider); } } @Override public Object getParent(Object element) { return null; } @Override public boolean hasChildren(Object element) { if (element instanceof RuleRepositoryInput) { return ((RuleRepositoryInput)element).getChildren().length > 0; } else if (element instanceof SystemRulesNode) { return ((SystemRulesNode)element).getChildren().length > 0; } else if (element instanceof CustomRulesNode) { return ((CustomRulesNode)element).getChildren().length > 0; } else if (element instanceof RuleProvider || element instanceof CustomRuleProvider) { return true; // file node } else if (element instanceof Node) { return getChildren(element).length > 0; } return false; } // // Label provider // @Override public String getText(Object element) { String result = null; if (element instanceof SystemRulesNode) { return Messages.systemRulesets; } else if (element instanceof CustomRulesNode) { return Messages.customRulesets; } else if (element instanceof RuleProvider) { RuleProvider ruleProvider = (RuleProvider)element; return ruleProvider.getProviderID(); } else if (element instanceof Rule) { return ((Rule)element).getRuleID(); } else if (element instanceof RulesetFileNode) { return ((RulesetFileNode)element).getName(); } else if (element instanceof CustomRuleProvider) { CustomRuleProvider provider = (CustomRuleProvider)element; return XMLRulesetModelUtil.getRulesetId(provider.getLocationURI()); } if (element instanceof Node) { result = XMLRulesetModelUtil.getRuleId((Node)element); } result = TextProcessor.process(result); return result != null ? result : ""; //$NON-NLS-1$ } @SuppressWarnings("incomplete-switch") public Image getImage(Object object) { Image image = null; if (object instanceof SystemRulesNode) { image = REPOSITORY; } else if (object instanceof CustomRulesNode) { image = REPOSITORY; } else if (object instanceof RuleProvider) { image = RULE_SET; } else if (object instanceof CustomRuleProvider) { return RULE_SET; } else if (object instanceof RulesetFileNode) { RulesetFileNode node = (RulesetFileNode)object; switch (node.getRuleProviderType()) { case XML: image = XML_RULE_PROVIDER; break; case GROOVY: image = GROOVY_RULE_PROVIDER; break; } } else if (object instanceof Rule) { image = RULE; } else if (object instanceof Node) { image = RULE; } return image; } @Override public boolean isLabelProperty(Object element, String property) { return false; } @Override public StyledString getStyledText(Object element) { StyledString style = new StyledString(getText(element)); if (element instanceof SystemRulesNode && ((SystemRulesNode)element).getChildren().length == 0) { style.append(" [" + "Start RHAMT to view the system rules" + "]", StyledString.DECORATIONS_STYLER); } else if (element instanceof CustomRuleProvider || element instanceof RuleProvider) { style.append(" (" + (getChildren(element).length - 1) + ")", StyledString.COUNTER_STYLER); } else if (element instanceof RulesetFileNode) { style.append(" [" + ((RulesetFileNode)element).getFile().getPath() + "]", StyledString.DECORATIONS_STYLER); } return style; } @Override public void removeListener(ILabelProviderListener listener) {} @Override public void addListener(ILabelProviderListener listener) {} @Override public void dispose() {} }