getSupportedFormats() {
56 | return EnumSet.of(BITMAP, GIF, TIFF, JPEG, PNG, SVG, DOT);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz.ui/src/com/abstratt/graphviz/ui/FileBrowserField.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.graphviz.ui;
2 |
3 | import java.io.File;
4 |
5 | import org.eclipse.swt.SWT;
6 | import org.eclipse.swt.events.DisposeEvent;
7 | import org.eclipse.swt.events.DisposeListener;
8 | import org.eclipse.swt.events.KeyAdapter;
9 | import org.eclipse.swt.events.KeyEvent;
10 | import org.eclipse.swt.events.ModifyEvent;
11 | import org.eclipse.swt.events.ModifyListener;
12 | import org.eclipse.swt.events.SelectionAdapter;
13 | import org.eclipse.swt.events.SelectionEvent;
14 | import org.eclipse.swt.layout.GridData;
15 | import org.eclipse.swt.layout.GridLayout;
16 | import org.eclipse.swt.widgets.Button;
17 | import org.eclipse.swt.widgets.Composite;
18 | import org.eclipse.swt.widgets.FileDialog;
19 | import org.eclipse.swt.widgets.Text;
20 |
21 | /**
22 | * Just a combination text entry box and browse button. Right now it's
23 | * specialized for browsing files but it would be easy to refactor to do just
24 | * about anything: just extract doBrowse().
25 | *
26 | * Cribbed from StringButtonFieldEditor and friends.
27 | *
28 | * @author bronson
29 | */
30 |
31 | public class FileBrowserField extends Composite {
32 | private Text text;
33 | private Button button;
34 |
35 | public FileBrowserField(Composite parent) {
36 | super(parent, 0);
37 |
38 | GridLayout gridLayout = new GridLayout();
39 | gridLayout.numColumns = 2;
40 | setLayout(gridLayout);
41 |
42 | text = new Text(this, SWT.SINGLE | SWT.BORDER);
43 | text.addModifyListener(new ModifyListener() {
44 | public void modifyText(ModifyEvent e) {
45 | valueChanged();
46 | }
47 | });
48 | text.addKeyListener(new KeyAdapter() {
49 | @Override
50 | public void keyReleased(KeyEvent e) {
51 | valueChanged();
52 | }
53 | });
54 |
55 | // tell the text field to use up as much horizontal space as it can
56 | GridData gridData = new GridData();
57 | gridData.horizontalAlignment = GridData.FILL;
58 | gridData.grabExcessHorizontalSpace = true;
59 | text.setLayoutData(gridData);
60 |
61 | button = new Button(this, SWT.PUSH);
62 | button.setText("Browse");
63 | button.setFont(getFont());
64 | button.addSelectionListener(new SelectionAdapter() {
65 | @Override
66 | public void widgetSelected(SelectionEvent e) {
67 | String newValue = doBrowse();
68 | if (newValue != null) {
69 | setText(newValue);
70 | }
71 | }
72 | });
73 |
74 | button.addDisposeListener(new DisposeListener() {
75 | public void widgetDisposed(DisposeEvent event) {
76 | button = null;
77 | }
78 | });
79 | }
80 |
81 | protected String doBrowse() {
82 | File f = new File(text.getText());
83 | if (!f.exists()) {
84 | f = null;
85 | }
86 | File d = getFile(f);
87 | if (d == null) {
88 | return null;
89 | }
90 | return d.getAbsolutePath();
91 | }
92 |
93 | private File getFile(File startingDirectory) {
94 | FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
95 | if (startingDirectory != null) {
96 | dialog.setFileName(startingDirectory.getPath());
97 | }
98 | String file = dialog.open();
99 | if (file != null) {
100 | file = file.trim();
101 | if (file.length() > 0) {
102 | return new File(file);
103 | }
104 | }
105 |
106 | return null;
107 | }
108 |
109 | public String getText() {
110 | return text != null ? text.getText() : "";
111 | }
112 |
113 | /*
114 | * (non-Javadoc)
115 | *
116 | * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
117 | */
118 | @Override
119 | public void setEnabled(boolean enabled) {
120 | text.setEnabled(enabled);
121 | button.setEnabled(enabled);
122 | super.setEnabled(enabled);
123 | }
124 |
125 | /**
126 | * Sets this field editor's value ensuring that textChanged() is called.
127 | *
128 | * @param value
129 | * the new value, or null
meaning the empty string
130 | */
131 | public void setText(String value) {
132 | if (value == null) {
133 | value = "";
134 | }
135 |
136 | if (!text.getText().equals(value)) {
137 | text.setText(value);
138 | valueChanged();
139 | }
140 | }
141 |
142 | /**
143 | * Called every time the text changes (i.e. every keypress or when the user
144 | * clicks on the browse button.
145 | *
146 | * Not called at init or teardown time.
147 | */
148 | public void valueChanged() {
149 | // by default do nothing
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz.ui/src/com/abstratt/graphviz/ui/GraphVizPreferencePage.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2007 EclipseGraphviz contributors.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * Scott Bronson
10 | *******************************************************************************/
11 | package com.abstratt.graphviz.ui;
12 |
13 | import java.io.File;
14 |
15 | import org.eclipse.jface.dialogs.IMessageProvider;
16 | import org.eclipse.jface.preference.PreferencePage;
17 | import org.eclipse.swt.SWT;
18 | import org.eclipse.swt.events.SelectionAdapter;
19 | import org.eclipse.swt.events.SelectionEvent;
20 | import org.eclipse.swt.layout.GridData;
21 | import org.eclipse.swt.layout.GridLayout;
22 | import org.eclipse.swt.widgets.Button;
23 | import org.eclipse.swt.widgets.Composite;
24 | import org.eclipse.swt.widgets.Control;
25 | import org.eclipse.swt.widgets.Group;
26 | import org.eclipse.swt.widgets.Text;
27 | import org.eclipse.ui.IWorkbench;
28 | import org.eclipse.ui.IWorkbenchPreferencePage;
29 |
30 | import com.abstratt.graphviz.GraphVizActivator;
31 | import com.abstratt.graphviz.GraphVizActivator.DotMethod;
32 |
33 | public class GraphVizPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
34 | /**
35 | * Utility method that creates a radio button instance and sets the default
36 | * layout data.
37 | *
38 | * @param parent
39 | * the parent for the new button
40 | * @param label
41 | * the label for the new button
42 | * @return the newly-created button
43 | */
44 |
45 | protected static Button createRadioButton(Composite parent, String label) {
46 | Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
47 | button.setText(label);
48 | return button;
49 | }
50 |
51 | private Button automaticDotButton;
52 | private Button specifyDotButton;
53 |
54 | private FileBrowserField dotBrowser;
55 | private Text commandLineText;
56 |
57 | /**
58 | * Creates the mildly complex radio buttons that the prefs dialog uses.
59 | *
60 | * @param group
61 | * The group to add the button to.
62 | * @param label
63 | * The text for the button's label
64 | * @param location
65 | * String to append to the label, null to append nothing and
66 | * disable the button.
67 | * @param method
68 | * If this matches the current method, the button is
69 | * automatically selected.
70 | * @return The new button.
71 | */
72 | private Button createButton(Group group, String label, boolean enabled, DotMethod method) {
73 | Button button;
74 |
75 | button = createRadioButton(group, label);
76 | button.setSelection(getCurrentDotMethod() == method);
77 | button.addSelectionListener(new SelectionAdapter() {
78 | @Override
79 | public void widgetSelected(SelectionEvent e) {
80 | boolean enabled = specifyDotButton.getSelection();
81 | dotBrowser.setEnabled(enabled);
82 | dotBrowserChanged(null);
83 | }
84 | });
85 | button.setEnabled(enabled);
86 | return button;
87 | }
88 |
89 | /**
90 | * Creates the composite which will contain all the preference controls for
91 | * this page.
92 | *
93 | * @param parent
94 | * the parent composite
95 | * @return the composite for this page
96 | */
97 | protected Composite createComposite(Composite parent) {
98 | Composite composite = new Composite(parent, SWT.NONE);
99 | GridLayout layout = new GridLayout();
100 | layout.marginWidth = 0;
101 | layout.marginHeight = 0;
102 | composite.setLayout(layout);
103 | composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
104 | return composite;
105 | }
106 |
107 | /*
108 | * (non-Javadoc)
109 | *
110 | * @see org.eclipse.jface.preference.PreferencePage
111 | */
112 | @Override
113 | protected Control createContents(Composite parent) {
114 | Composite composite = createComposite(parent);
115 | createOpenModeGroup(composite);
116 | createCommandLineExtension(composite);
117 | applyDialogFont(composite);
118 | return composite;
119 | }
120 |
121 | /**
122 | * Creates widgets for editing the command-line extension string.
123 | *
124 | * @param composite
125 | */
126 | private void createCommandLineExtension(Composite composite) {
127 | Group group = new Group(composite, SWT.LEFT);
128 | GridLayout layout = new GridLayout();
129 | group.setLayout(layout);
130 | GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
131 | group.setLayoutData(data);
132 | group.setText("Additional command line options (prepended to options automatically generated)");
133 | commandLineText = new Text(group, SWT.SINGLE | SWT.BORDER);
134 |
135 | String existing = GraphVizActivator.getInstance().getCommandLineExtension();
136 | commandLineText.setText(existing == null ? "" : existing);
137 |
138 | data = new GridData();
139 | data.horizontalIndent = 20;
140 | data.horizontalAlignment = GridData.FILL;
141 | data.grabExcessHorizontalSpace = true;
142 | commandLineText.setLayoutData(data);
143 | }
144 |
145 | protected void createOpenModeGroup(Composite composite) {
146 | Group buttonComposite = new Group(composite, SWT.LEFT);
147 | GridLayout layout = new GridLayout();
148 | buttonComposite.setLayout(layout);
149 | GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
150 | buttonComposite.setLayoutData(data);
151 | buttonComposite.setText("Dot executable to use");
152 |
153 | GraphVizActivator graphviz = GraphVizActivator.getInstance();
154 | String detectedDotLocation = graphviz.autodetectDots();
155 | final boolean dotDetected = detectedDotLocation != null;
156 | automaticDotButton = createButton(buttonComposite, "Found in PATH variable: " + (dotDetected ? detectedDotLocation : "(none)"), true, DotMethod.AUTO);
157 | specifyDotButton = createButton(buttonComposite, "Specify Manually:", true, DotMethod.MANUAL);
158 |
159 | dotBrowser = new FileBrowserField(buttonComposite) {
160 | @Override
161 | public void valueChanged() {
162 | dotBrowserChanged(getText());
163 | }
164 | };
165 | dotBrowser.setText(graphviz.getManualDotPath());
166 | dotBrowser.setEnabled(getCurrentDotMethod() == DotMethod.MANUAL);
167 |
168 | data = new GridData();
169 | data.horizontalIndent = 20;
170 | data.horizontalAlignment = GridData.FILL;
171 | data.grabExcessHorizontalSpace = true;
172 | dotBrowser.setLayoutData(data);
173 | }
174 |
175 | public void dotBrowserChanged(String newText) {
176 | setErrorMessage(null);
177 | setMessage(null);
178 | if (newText == null) {
179 | newText = dotBrowser.getText();
180 | }
181 | if (specifyDotButton.getSelection()) {
182 | if (newText.length() == 0) {
183 | setErrorMessage("Please enter a path.");
184 | setValid(false);
185 | return;
186 | }
187 | File dotFile = new File(newText);
188 | String fileName = dotFile.getName();
189 | int extensionPos;
190 | while ((extensionPos = fileName.lastIndexOf('.')) > 0)
191 | fileName = fileName.substring(0, extensionPos);
192 | if (!dotFile.exists()) {
193 | setErrorMessage(newText + " doesn't exist");
194 | setValid(false);
195 | return;
196 | } else if (dotFile.isDirectory()) {
197 | setErrorMessage(newText + " is a directory");
198 | setValid(false);
199 | return;
200 | } else if (!GraphVizActivator.isExecutable(dotFile))
201 | setMessage(newText + " is not executable!", IMessageProvider.WARNING);
202 | else if (!GraphVizActivator.DOT_FILE_NAME.equalsIgnoreCase(fileName))
203 | setMessage("The file name should be " + GraphVizActivator.DOT_FILE_NAME, IMessageProvider.WARNING);
204 | }
205 | setValid(true);
206 | }
207 |
208 | /** Returns the Dot search method that is currently in effect */
209 | DotMethod getCurrentDotMethod() {
210 | return GraphVizActivator.getInstance().getDotSearchMethod();
211 | }
212 |
213 | /**
214 | * Scans the radio buttons and returns the dot method that the user has
215 | * selected.
216 | */
217 | DotMethod getNewDotMethod() {
218 | return specifyDotButton.getSelection() ? DotMethod.MANUAL : DotMethod.AUTO;
219 | }
220 |
221 | /**
222 | * @see IWorkbenchPreferencePage
223 | */
224 | public void init(IWorkbench workbench) {
225 | }
226 |
227 | /**
228 | * The default button has been pressed.
229 | */
230 | @Override
231 | protected void performDefaults() {
232 | DotMethod dotMethod = DotMethod.AUTO;
233 | automaticDotButton.setSelection(dotMethod == DotMethod.AUTO);
234 | specifyDotButton.setSelection(dotMethod == DotMethod.MANUAL);
235 | dotBrowser.setText("");
236 | commandLineText.setText("");
237 |
238 | super.performDefaults();
239 | }
240 |
241 | /**
242 | * The user has pressed OK or Apply. Store this page's values.
243 | */
244 | @Override
245 | public boolean performOk() {
246 | GraphVizActivator graphviz = GraphVizActivator.getInstance();
247 | graphviz.setDotSearchMethod(getNewDotMethod());
248 | graphviz.setManualDotPath(dotBrowser.getText());
249 | graphviz.setCommandLineExtension(commandLineText.getText());
250 | return true;
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz.ui/src/com/abstratt/graphviz/ui/RenderClipboardAction.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.graphviz.ui;
2 |
3 | import org.eclipse.jface.action.IAction;
4 | import org.eclipse.jface.viewers.ISelection;
5 | import org.eclipse.swt.dnd.Clipboard;
6 | import org.eclipse.swt.dnd.TextTransfer;
7 | import org.eclipse.swt.widgets.Display;
8 | import org.eclipse.ui.IViewActionDelegate;
9 | import org.eclipse.ui.IViewPart;
10 |
11 | import com.abstratt.imageviewer.GraphicalView;
12 |
13 | public class RenderClipboardAction implements IViewActionDelegate {
14 |
15 | private GraphicalView view;
16 |
17 | public void init(IViewPart view) {
18 | this.view = (GraphicalView) view;
19 | }
20 |
21 | public void run(IAction action) {
22 | Clipboard clipboard = new Clipboard(Display.getCurrent());
23 | String contents = (String) clipboard.getContents(TextTransfer.getInstance());
24 | if (contents != null) {
25 | view.setAutoSync(false);
26 | view.setContents(contents.getBytes(), new DOTGraphicalContentProvider());
27 | }
28 | }
29 |
30 | public void selectionChanged(IAction action, ISelection selection) {
31 | // don't care
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/.options:
--------------------------------------------------------------------------------
1 | com.abstratt.graphviz/debug=false
2 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.abstratt.graphviz
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.pde.ManifestBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.pde.SchemaBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.m2e.core.maven2Builder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.m2e.core.maven2Nature
31 | org.eclipse.pde.PluginNature
32 | org.eclipse.jdt.core.javanature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Bundle-ManifestVersion: 2
3 | Bundle-Name: Graphviz Plug-in
4 | Bundle-SymbolicName: com.abstratt.graphviz;singleton:=true
5 | Bundle-Version: 2.13.0
6 | Bundle-Vendor: Abstratt Technologies (Eclipse integration)
7 | Bundle-Activator: com.abstratt.graphviz.GraphVizActivator
8 | Require-Bundle: org.eclipse.osgi,
9 | org.eclipse.core.runtime,
10 | org.apache.commons.io,
11 | com.abstratt.pluginutils,
12 | org.eclipse.core.filesystem
13 | Export-Package: com.abstratt.graphviz
14 | Eclipse-LazyStart: true
15 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8
16 | Bundle-ActivationPolicy: lazy
17 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/build.properties:
--------------------------------------------------------------------------------
1 | source.. = src/
2 | output.. = bin/
3 | bin.includes = META-INF/,\
4 | .,\
5 | plugin.xml
6 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.abstratt.eclipsegraphviz
6 | com.abstratt.graphviz
7 | 2.13.0
8 | eclipse-plugin
9 |
10 | com.abstratt.eclipsegraphviz.parent
11 | com.abstratt.eclipsegraphviz
12 | 2.13.0
13 | ../..
14 |
15 |
16 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/src/com/abstratt/graphviz/GraphViz.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2007 EclipseGraphviz contributors.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * abstratt technologies
10 | * Scott Bronson
11 | *******************************************************************************/
12 | package com.abstratt.graphviz;
13 |
14 | import java.io.ByteArrayInputStream;
15 | import java.io.ByteArrayOutputStream;
16 | import java.io.File;
17 | import java.io.FileOutputStream;
18 | import java.io.IOException;
19 | import java.io.InputStream;
20 | import java.nio.charset.StandardCharsets;
21 | import java.util.ArrayList;
22 | import java.util.Arrays;
23 | import java.util.List;
24 |
25 | import org.apache.commons.io.FileUtils;
26 | import org.apache.commons.io.IOUtils;
27 | import org.eclipse.core.runtime.CoreException;
28 | import org.eclipse.core.runtime.IPath;
29 | import org.eclipse.core.runtime.IStatus;
30 | import org.eclipse.core.runtime.MultiStatus;
31 | import org.eclipse.core.runtime.Platform;
32 | import org.eclipse.core.runtime.Status;
33 |
34 | import com.abstratt.graphviz.ProcessController.TimeOutException;
35 | import com.abstratt.pluginutils.LogUtils;
36 |
37 | /**
38 | * The entry point to the Graphviz support API.
39 | */
40 | // TODO generate and load have a lot in common, refactor
41 | // TODO we should just pass the input stream directly (or buffered) to Graphviz,
42 | // instead of creating a temporary file
43 | public class GraphViz {
44 | private static final String DOT_EXTENSION = ".dot"; //$NON-NLS-1$
45 | private static final String TMP_FILE_PREFIX = "graphviz"; //$NON-NLS-1$
46 | private static final int MAX_DOT_LENGTH_TO_LOG = 4 * 64 * 1024;
47 |
48 | public static void generate(final InputStream input, String format, int dimensionX, int dimensionY,
49 | IPath outputLocation) throws CoreException {
50 | MultiStatus status = new MultiStatus(GraphVizActivator.ID, 0, "Errors occurred while running Graphviz", null);
51 | File dotInputFile = null, dotOutputFile = outputLocation.toFile();
52 | // we keep the input in memory so we can include it in error messages
53 | ByteArrayOutputStream dotContents = new ByteArrayOutputStream();
54 | try {
55 | // determine the temp input location
56 | dotInputFile = File.createTempFile(TMP_FILE_PREFIX, DOT_EXTENSION);
57 | // dump the contents from the input stream into the temporary file
58 | // to be submitted to dot
59 | FileOutputStream tmpDotOutputStream = null;
60 | try {
61 | IOUtils.copy(input, dotContents);
62 | tmpDotOutputStream = new FileOutputStream(dotInputFile);
63 | IOUtils.copy(new ByteArrayInputStream(dotContents.toByteArray()), tmpDotOutputStream);
64 | } finally {
65 | IOUtils.closeQuietly(tmpDotOutputStream);
66 | }
67 | IStatus result = runDot(format, dimensionX, dimensionY, dotInputFile, dotOutputFile);
68 | status.add(result);
69 | System.out.println(dotContents.toString());
70 | if (!result.isOK()) {
71 | LogUtils.debug(GraphVizActivator.ID, "A problem was detected, dumping DOT output to console");
72 | System.out.println(dotContents.toString());
73 | }
74 | if (dotOutputFile.isFile() && dotOutputFile.length() > 0) {
75 | // success! (or kind of)
76 | return;
77 | }
78 | } catch (IOException e) {
79 | status.add(new Status(IStatus.ERROR, GraphVizActivator.ID, "", e));
80 | } finally {
81 | dotInputFile.delete();
82 | IOUtils.closeQuietly(input);
83 | }
84 | throw new CoreException(status);
85 | }
86 |
87 | /**
88 | * Higher-level API for launching a GraphViz transformation.
89 | *
90 | * @return the resulting image, never null
91 | * @throws CoreException
92 | * if any error occurs
93 | */
94 | public static byte[] load(final InputStream input, String format, int dimensionX, int dimensionY)
95 | throws CoreException {
96 | MultiStatus status = new MultiStatus(GraphVizActivator.ID, 0, "Errors occurred while running Graphviz", null);
97 | File dotInputFile = null, dotOutputFile = null;
98 | // we keep the input in memory so we can include it in error messages
99 | ByteArrayOutputStream dotContents = new ByteArrayOutputStream();
100 | try {
101 | // determine the temp input and output locations
102 | dotInputFile = File.createTempFile(TMP_FILE_PREFIX, DOT_EXTENSION);
103 | dotOutputFile = File.createTempFile(TMP_FILE_PREFIX, "." + format);
104 | // we created the output file just so we would know an output
105 | // location to pass to dot
106 | dotOutputFile.delete();
107 |
108 | // dump the contents from the input stream into the temporary file
109 | // to be submitted to dot
110 | byte[] contentsAsArray = null;
111 | try (FileOutputStream tmpDotOutputStream = new FileOutputStream(dotInputFile)) {
112 | IOUtils.copy(input, dotContents);
113 | contentsAsArray = dotContents.toByteArray();
114 | IOUtils.copy(new ByteArrayInputStream(contentsAsArray), tmpDotOutputStream);
115 | }
116 |
117 | IStatus result = runDot(format, dimensionX, dimensionY, dotInputFile, dotOutputFile);
118 |
119 | status.add(result);
120 | status.add(logInput(contentsAsArray));
121 | if (dotOutputFile.isFile()) {
122 | if (!result.isOK() && Platform.inDebugMode())
123 | LogUtils.log(status);
124 | return FileUtils.readFileToByteArray(dotOutputFile);
125 | }
126 | } catch (IOException e) {
127 | status.add(new Status(IStatus.ERROR, GraphVizActivator.ID, "", e));
128 | } finally {
129 | dotInputFile.delete();
130 | dotOutputFile.delete();
131 | IOUtils.closeQuietly(input);
132 | }
133 | throw new CoreException(status);
134 | }
135 |
136 | public static IStatus runDot(String format, int dimensionX, int dimensionY, File dotInput, File dotOutput) {
137 | // build the command line
138 | double dpi = 96;
139 | double widthInInches = dimensionX / dpi;
140 | double heightInInches = dimensionY / dpi;
141 | List cmd = new ArrayList();
142 | cmd.add("-o" + dotOutput.getAbsolutePath());
143 | cmd.add("-T" + format);
144 | if (widthInInches > 0 && heightInInches > 0)
145 | cmd.add("-Gsize=" + widthInInches + ',' + heightInInches);
146 | cmd.add(dotInput.getAbsolutePath());
147 | return runDot(cmd.toArray(new String[cmd.size()]));
148 | }
149 |
150 | private static IStatus logInput(byte[] dotContents) {
151 | String dotInput = new String(dotContents, 0, Math.min(dotContents.length, MAX_DOT_LENGTH_TO_LOG), StandardCharsets.UTF_8);
152 | return new Status(IStatus.INFO, GraphVizActivator.ID, "dot input was:\n" + dotInput, null);
153 | }
154 |
155 | /**
156 | * Bare bones API for launching dot. Command line options are passed to
157 | * Graphviz as specified in the options parameter. The location for dot is
158 | * obtained from the user preferences.
159 | *
160 | * @param options
161 | * command line options for dot
162 | * @return a non-zero integer if errors happened
163 | * @throws IOException
164 | */
165 | public static IStatus runDot(String... options) {
166 | IPath dotFullPath = GraphVizActivator.getInstance().getDotLocation();
167 | if (dotFullPath == null || dotFullPath.isEmpty())
168 | return new Status(
169 | IStatus.ERROR,
170 | GraphVizActivator.ID,
171 | "dot.exe/dot not found in PATH. Please install it from graphviz.org, update the PATH or specify the absolute path in the preferences.");
172 | if (!dotFullPath.toFile().isFile())
173 | return new Status(IStatus.ERROR, GraphVizActivator.ID, "Could not find Graphviz dot at \"" + dotFullPath
174 | + "\"");
175 | List cmd = new ArrayList();
176 | cmd.add(dotFullPath.toOSString());
177 | // insert user custom options
178 | String commandLineExtension = GraphVizActivator.getInstance().getCommandLineExtension();
179 | if (commandLineExtension != null) {
180 | String[] tokens = commandLineExtension.split(" ");
181 | cmd.addAll(Arrays.asList(tokens));
182 | }
183 | cmd.addAll(Arrays.asList(options));
184 |
185 | ByteArrayOutputStream errorOutput = new ByteArrayOutputStream();
186 | try {
187 | final ProcessController controller = new ProcessController(90000, cmd.toArray(new String[cmd.size()]),
188 | null, dotFullPath.removeLastSegments(1).toFile());
189 | controller.forwardErrorOutput(errorOutput);
190 | controller.forwardOutput(System.out);
191 | controller.forwardInput(System.in);
192 | int exitCode = controller.execute();
193 | if (exitCode != 0)
194 | return new Status(IStatus.WARNING, GraphVizActivator.ID, "Graphviz exit code: " + exitCode + "."
195 | + createContentMessage(errorOutput));
196 | if (errorOutput.size() > 0)
197 | return new Status(IStatus.WARNING, GraphVizActivator.ID, createContentMessage(errorOutput));
198 | return Status.OK_STATUS;
199 | } catch (TimeOutException e) {
200 | return new Status(IStatus.ERROR, GraphVizActivator.ID, "Graphviz process did not finish in a timely way."
201 | + createContentMessage(errorOutput));
202 | } catch (InterruptedException e) {
203 | return new Status(IStatus.ERROR, GraphVizActivator.ID, "Unexpected exception executing Graphviz."
204 | + createContentMessage(errorOutput), e);
205 | } catch (IOException e) {
206 | return new Status(IStatus.ERROR, GraphVizActivator.ID, "Unexpected exception executing Graphviz."
207 | + createContentMessage(errorOutput), e);
208 | }
209 | }
210 |
211 | private static String createContentMessage(ByteArrayOutputStream errorOutput) {
212 | if (errorOutput.size() == 0)
213 | return "";
214 | return " dot produced the following error output: \n" + errorOutput;
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/src/com/abstratt/graphviz/GraphVizActivator.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2007 EclipseGraphviz contributors.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * abstratt technologies
10 | * Scott Bronson
11 | *******************************************************************************/
12 | package com.abstratt.graphviz;
13 |
14 | import java.io.File;
15 | import java.io.FileFilter;
16 | import java.nio.file.Files;
17 |
18 | import org.eclipse.core.runtime.IPath;
19 | import org.eclipse.core.runtime.Path;
20 | import org.eclipse.core.runtime.Platform;
21 | import org.eclipse.core.runtime.preferences.IEclipsePreferences;
22 | import org.eclipse.core.runtime.preferences.InstanceScope;
23 | import org.osgi.framework.BundleActivator;
24 | import org.osgi.framework.BundleContext;
25 | import org.osgi.service.prefs.BackingStoreException;
26 | import org.osgi.service.prefs.Preferences;
27 |
28 | import com.abstratt.pluginutils.LogUtils;
29 |
30 | public class GraphVizActivator implements BundleActivator {
31 |
32 | /**
33 | * DotLocation keeps track of how the user wants to select the dot
34 | * executable. We include strings for each term so that the settings files
35 | * remain human readable.
36 | */
37 | public enum DotMethod {
38 | AUTO, MANUAL;
39 |
40 | /**
41 | * Given a string, looks up the corresponding DotMethod. If no match,
42 | * returns the default AUTO.
43 | */
44 | static public DotMethod find(String term) {
45 | for (DotMethod p : DotMethod.values()) {
46 | if (p.name().equals(term)) {
47 | return p;
48 | }
49 | }
50 | return AUTO;
51 | }
52 | }
53 |
54 | public static final String DOT_SEARCH_METHOD = "dotSearchMethod";
55 | // The manual path is entered by the user. It should never be changed or
56 | // deleted except by the user.
57 | public static final String DOT_MANUAL_PATH = "dotManualPath";
58 |
59 | public static final String DOT_FILE_NAME = "dot";
60 |
61 | public static final String COMMAND_LINE = "commandLineExtension";
62 |
63 | public static String ID = GraphVizActivator.class.getPackage().getName();
64 |
65 | private static GraphVizActivator instance;
66 |
67 | public static GraphVizActivator getInstance() {
68 | return instance;
69 | }
70 |
71 | /**
72 | * Returns whether the given file is executable. Depending on the platform
73 | * we might not get this right.
74 | *
75 | * TODO find a better home for this function
76 | */
77 | public static boolean isExecutable(File file) {
78 | if (!file.isFile())
79 | return false;
80 | if (Platform.getOS().equals(Platform.OS_WIN32))
81 | // executable attribute is a *ix thing, on Windows all files are
82 | // executable
83 | return true;
84 | return Files.isExecutable(file.toPath());
85 | }
86 |
87 | public static void logUnexpected(String message, Exception e) {
88 | LogUtils.logError(ID, message, e);
89 | }
90 |
91 | // store paths as strings so they won't get screwed up by platform issues.
92 |
93 | /**
94 | * Path to autodetected dot or null if it can't be found. See
95 | * autodetectDots().
96 | */
97 | private String autodetectedDotLocation;
98 |
99 | /**
100 | * The path the bundled Graphviz install was extracted to (null if not
101 | * found/looked up).
102 | */
103 |
104 | public GraphVizActivator() {
105 | instance = this;
106 | }
107 |
108 | /**
109 | * This routine browses through the user's PATH looking for dot executables.
110 | *
111 | * @return the absolute path if a suitable dot is found, null if not. This
112 | * is normally called once at plugin startup but it can also be
113 | * called while the plugin is running (in case user has installed
114 | * dot without restarting Eclipse).
115 | */
116 | public String autodetectDots() {
117 | autodetectedDotLocation = null;
118 | String paths = System.getenv("PATH");
119 | for (String path : paths.split(File.pathSeparator)) {
120 | File directory = new File(path);
121 | File[] matchingFiles = directory.listFiles(new ExecutableFinder(DOT_FILE_NAME));
122 | if (matchingFiles != null && matchingFiles.length > 0) {
123 | File found = matchingFiles[0];
124 | autodetectedDotLocation = found.getAbsolutePath();
125 | break;
126 | }
127 | }
128 | return autodetectedDotLocation;
129 | }
130 |
131 | private static class ExecutableFinder implements FileFilter {
132 | private String nameToMatch;
133 |
134 | public ExecutableFinder(String nameToMatch) {
135 | this.nameToMatch = nameToMatch;
136 | }
137 |
138 | public boolean accept(File candidate) {
139 | if (!candidate.getName().equalsIgnoreCase(nameToMatch)
140 | && !candidate.getName().startsWith(nameToMatch + '.'))
141 | return false;
142 | boolean executable = isExecutable(candidate);
143 | return executable;
144 | }
145 | }
146 |
147 | // preference getters and setters
148 |
149 | /**
150 | * Gets the path to the dot executable. It takes user's preferences into
151 | * account so it should always do the right thing.
152 | */
153 | public IPath getDotLocation() {
154 | final String manualLocation = getManualDotPath();
155 | DotMethod dotSearchMethod = getDotSearchMethod();
156 | switch (dotSearchMethod) {
157 | case AUTO:
158 | return autodetectedDotLocation != null ? new Path(autodetectedDotLocation) : null;
159 | case MANUAL:
160 | return manualLocation != null ? new Path(manualLocation) : null;
161 | }
162 | // can't never get here
163 | throw new IllegalStateException("Unexpected value for dotSearchMethod: " + dotSearchMethod);
164 | }
165 |
166 | public DotMethod getDotSearchMethod() {
167 | String value = getPreference(DOT_SEARCH_METHOD);
168 | return value != null ? DotMethod.find(value) : DotMethod.AUTO;
169 | }
170 |
171 | public File getGraphVizDirectory() {
172 | IPath dotLocation = getDotLocation();
173 | return dotLocation == null ? null : dotLocation.removeLastSegments(1).toFile();
174 | }
175 |
176 | public String getManualDotPath() {
177 | return getPreference(DOT_MANUAL_PATH);
178 | }
179 |
180 | public String getCommandLineExtension() {
181 | return getPreference(COMMAND_LINE);
182 | }
183 |
184 | public void setCommandLineExtension(String commandLineExtension) {
185 | setPreference(COMMAND_LINE, commandLineExtension);
186 | }
187 |
188 | /** Returns the preference with the given name */
189 | public String getPreference(String preference_name) {
190 | Preferences node = Platform.getPreferencesService().getRootNode().node(InstanceScope.SCOPE)
191 | .node(GraphVizActivator.ID);
192 | return node.get(preference_name, null);
193 | }
194 |
195 | public void setDotSearchMethod(DotMethod dotMethod) {
196 | setPreference(DOT_SEARCH_METHOD, dotMethod.name());
197 | }
198 |
199 | public void setManualDotPath(String newLocation) {
200 | setPreference(DOT_MANUAL_PATH, newLocation);
201 | }
202 |
203 | /** Sets the given preference to the given value */
204 | public void setPreference(String preferenceName, String value) {
205 | IEclipsePreferences root = Platform.getPreferencesService().getRootNode();
206 | Preferences node = root.node(InstanceScope.SCOPE).node(GraphVizActivator.ID);
207 | try {
208 | node.sync();
209 | node.put(preferenceName, value);
210 | node.flush();
211 | } catch (BackingStoreException e) {
212 | LogUtils.logError(ID, "Error updating preferences.", e);
213 | }
214 | }
215 |
216 | public void start(BundleContext context) throws Exception {
217 | // try to find any installed copies of dot
218 | autodetectDots();
219 | if (autodetectedDotLocation != null) {
220 | LogUtils.logInfo(getClass().getPackage().getName(), "Detected dot at " + autodetectedDotLocation, null);
221 | } else if (getDotSearchMethod() == DotMethod.AUTO) {
222 | LogUtils.logWarning(
223 | ID,
224 | "Could not find a suitable dot executable. Please specify one using Window -> Preferences -> Graphviz.",
225 | null);
226 | }
227 | }
228 |
229 | public void stop(BundleContext context) throws Exception {
230 | // nothing to do
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.graphviz/src/com/abstratt/graphviz/ProcessController.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2004, 2006 IBM Corporation and others.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * IBM Corporation - initial API and implementation
10 | *******************************************************************************/
11 | package com.abstratt.graphviz;
12 |
13 | import java.io.File;
14 | import java.io.IOException;
15 | import java.io.InputStream;
16 | import java.io.OutputStream;
17 | import java.util.UUID;
18 |
19 | /**
20 | * Executes an external process synchronously, allowing the client to define a
21 | * maximum amount of time for the process to complete.
22 | */
23 | public class ProcessController {
24 | /**
25 | * Thrown when a process being executed exceeds the maximum amount of time
26 | * allowed for it to complete.
27 | */
28 | public class TimeOutException extends Exception {
29 | /**
30 | * All serializable objects should have a stable serialVersionUID
31 | */
32 | private static final long serialVersionUID = 1L;
33 |
34 | public TimeOutException() {
35 | super();
36 | }
37 |
38 | public TimeOutException(String message) {
39 | super(message);
40 | }
41 | }
42 |
43 | private boolean finished;
44 | private OutputStream forwardStdErr;
45 | private InputStream forwardStdIn;
46 | private OutputStream forwardStdOut;
47 | private boolean killed;
48 | private String[] params;
49 | private Process process;
50 | private long startupTime;
51 | private long timeLimit;
52 | private String[] env;
53 | private File baseDir;
54 |
55 | /**
56 | * Constructs an instance of ProcessController. This does not creates an OS
57 | * process. run()
does that.
58 | *
59 | * @param timeout
60 | * the maximum time the process should take to run
61 | * @param params
62 | * the parameters to be passed to the controlled process
63 | */
64 | public ProcessController(long timeout, String[] params, String[] env, File baseDir) {
65 | timeLimit = timeout;
66 | this.params = params;
67 | this.env = env;
68 | this.baseDir = baseDir;
69 | }
70 |
71 | private void controlProcess() {
72 | new Thread("Process controller") {
73 | @Override
74 | public void run() {
75 | while (!isFinished() && !timedOut())
76 | synchronized (this) {
77 | try {
78 | wait(100);
79 | } catch (InterruptedException e) {
80 | break;
81 | }
82 | }
83 | kill();
84 | }
85 | }.start();
86 | }
87 |
88 | /**
89 | * Causes the process to start executing. This call will block until the
90 | * process has completed. If timeout
is specified, the process
91 | * will be interrupted if it takes more than the specified amount of time to
92 | * complete, causing a TimedOutException
to be thrown.
93 | * Specifying zero as timeout
means the process is not time
94 | * constrained.
95 | *
96 | * @return the process exit value
97 | * @throws InterruptedException
98 | * @throws IOException
99 | * @throws TimeOutException
100 | * if the process did not complete in time
101 | */
102 | public int execute() throws InterruptedException, IOException, TimeOutException {
103 | startupTime = System.currentTimeMillis();
104 | process = Runtime.getRuntime().exec(params, env, baseDir);
105 | if (forwardStdErr != null)
106 | forwardStream("stderr", process.getErrorStream(), forwardStdErr);
107 | if (forwardStdOut != null)
108 | forwardStream("stdout", process.getInputStream(), forwardStdOut);
109 | if (forwardStdIn != null)
110 | forwardStream("stdin", forwardStdIn, process.getOutputStream());
111 | if (timeLimit > 0)
112 | // ensures process execution time does not exceed the time limit
113 | controlProcess();
114 | try {
115 | return process.waitFor();
116 | } finally {
117 | markFinished();
118 | if (wasKilled())
119 | throw new TimeOutException();
120 | }
121 | }
122 |
123 | /**
124 | * Forwards the process standard error output to the given output stream.
125 | * Must be called before execution has started.
126 | *
127 | * @param err
128 | * an output stream where to forward the process standard error
129 | * output to
130 | */
131 | public void forwardErrorOutput(OutputStream err) {
132 | forwardStdErr = err;
133 | }
134 |
135 | /**
136 | * Forwards the given input stream to the process standard input. Must be
137 | * called before execution has started.
138 | *
139 | * @param in
140 | * an input stream where the process standard input will be
141 | * forwarded to
142 | */
143 | public void forwardInput(InputStream in) {
144 | forwardStdIn = in;
145 | }
146 |
147 | /**
148 | * Forwards the process standard output to the given output stream. Must be
149 | * called before execution has started.
150 | *
151 | * @param out
152 | * an output stream where to forward the process standard output
153 | * to
154 | */
155 | public void forwardOutput(OutputStream out) {
156 | forwardStdOut = out;
157 | }
158 |
159 | private void forwardStream(final String name, final InputStream in, final OutputStream out) {
160 | new Thread("Stream forwarder [" + name + "]") {
161 | @Override
162 | public void run() {
163 | String key = UUID.randomUUID().toString();
164 | System.out.println("Started " + getName() + " - " + key);
165 | try {
166 | while (!isFinished()) {
167 | while (safeIsAvailable(in) > 0)
168 | out.write(in.read());
169 | synchronized (this) {
170 | this.wait(100);
171 | }
172 | }
173 | out.flush();
174 | } catch (IOException e) {
175 | GraphVizActivator.logUnexpected(null, e);
176 | } catch (InterruptedException e) {
177 | GraphVizActivator.logUnexpected(null, e);
178 | } finally {
179 | System.out.println("Finished " + getName() + " - " + key);
180 | }
181 | }
182 |
183 | private int safeIsAvailable(InputStream in) {
184 | try {
185 | return in.available();
186 | } catch (IOException e) {
187 | // stream has been closed
188 | return 0;
189 | }
190 | }
191 | }.start();
192 | }
193 |
194 | /**
195 | * Returns the controled process. Will return null
before
196 | * execute
is called.
197 | *
198 | * @return the underlying process
199 | */
200 | public Process getProcess() {
201 | return process;
202 | }
203 |
204 | protected synchronized boolean isFinished() {
205 | return finished;
206 | }
207 |
208 | /**
209 | * Kills the process. Does nothing if it has been finished already.
210 | */
211 | public void kill() {
212 | synchronized (this) {
213 | if (isFinished())
214 | return;
215 | killed = true;
216 | }
217 | process.destroy();
218 | }
219 |
220 | private synchronized void markFinished() {
221 | finished = true;
222 | notifyAll();
223 | }
224 |
225 | protected synchronized boolean timedOut() {
226 | return System.currentTimeMillis() - startupTime > timeLimit;
227 | }
228 |
229 | /**
230 | * Returns whether the process was killed due to a time out.
231 | *
232 | * @return true
if the process was killed, false
233 | * if the completed normally
234 | */
235 | public boolean wasKilled() {
236 | return killed;
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.abstratt.imageviewer
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.pde.ManifestBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.pde.SchemaBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.m2e.core.maven2Builder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.m2e.core.maven2Nature
31 | org.eclipse.pde.PluginNature
32 | org.eclipse.jdt.core.javanature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Bundle-ManifestVersion: 2
3 | Bundle-Name: Generic Image Viewer Plug-in
4 | Bundle-SymbolicName: com.abstratt.imageviewer;singleton:=true
5 | Bundle-Version: 2.13.0
6 | Bundle-Activator: com.abstratt.imageviewer.Activator
7 | Bundle-Vendor: Abstratt Technologies
8 | Require-Bundle: org.eclipse.core.runtime,
9 | org.eclipse.swt;visibility:=reexport,
10 | org.eclipse.jface;visibility:=reexport,
11 | org.eclipse.core.contenttype,
12 | org.eclipse.core.resources,
13 | org.eclipse.ui,
14 | org.apache.commons.io,
15 | com.abstratt.pluginutils,
16 | com.abstratt.content,
17 | org.apache.commons.beanutils
18 | Import-Package: org.eclipse.core.runtime
19 | Eclipse-LazyStart: true
20 | Export-Package: com.abstratt.imageviewer
21 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8
22 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/build.properties:
--------------------------------------------------------------------------------
1 | source.. = src/
2 | output.. = bin/
3 | bin.includes = META-INF/,\
4 | .,\
5 | plugin.xml,\
6 | icons/
7 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/copyviewtoclipboard_tsk.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/copyviewtoclipboard_tsk.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/dsave_edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/dsave_edit.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/esave_edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/esave_edit.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/paste_edit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/paste_edit.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/sample.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/icons/synced.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abstratt/eclipsegraphviz/1da8bb0fef7496fb8a7e0490eee7425c5fc62751/plugins/com.abstratt.imageviewer/icons/synced.gif
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
9 |
11 |
12 |
14 |
15 |
16 |
17 |
19 |
22 |
23 |
29 |
30 |
35 |
36 |
41 |
42 |
43 |
44 |
46 |
52 |
53 |
56 |
57 |
58 |
60 |
63 |
72 |
73 |
81 |
82 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.abstratt.eclipsegraphviz
6 | com.abstratt.imageviewer
7 | 2.13.0
8 | eclipse-plugin
9 |
10 | com.abstratt.eclipsegraphviz.parent
11 | com.abstratt.eclipsegraphviz
12 | 2.13.0
13 | ../..
14 |
15 |
16 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/schema/graphical_content_provider.exsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | An extension point for implementors of IGraphicalContentProvider.
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | The implementation of IGraphicalContentProvider.
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | [Enter the first release in which this extension point appears.]
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | [Enter extension point usage example here.]
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | [Enter API information here.]
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | [Enter information about supplied implementation of this extension point.]
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/AbstractGraphicalContentProvider.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 |
6 | import org.apache.commons.io.FileUtils;
7 | import org.eclipse.core.runtime.CoreException;
8 | import org.eclipse.core.runtime.IPath;
9 | import org.eclipse.core.runtime.IProgressMonitor;
10 | import org.eclipse.core.runtime.IStatus;
11 | import org.eclipse.core.runtime.Status;
12 | import org.eclipse.core.runtime.jobs.ISchedulingRule;
13 | import org.eclipse.core.runtime.jobs.Job;
14 | import org.eclipse.jface.viewers.Viewer;
15 | import org.eclipse.swt.SWT;
16 | import org.eclipse.swt.graphics.GC;
17 | import org.eclipse.swt.graphics.Image;
18 | import org.eclipse.swt.graphics.ImageData;
19 | import org.eclipse.swt.graphics.ImageLoader;
20 | import org.eclipse.swt.graphics.Point;
21 | import org.eclipse.swt.widgets.Display;
22 |
23 | import com.abstratt.pluginutils.LogUtils;
24 |
25 | public abstract class AbstractGraphicalContentProvider implements IGraphicalContentProvider {
26 |
27 | private Image image;
28 |
29 | private Point suggestedSize;
30 |
31 | private ContentLoader loaderJob = new ContentLoader();
32 |
33 | public final static ISchedulingRule CONTENT_LOADING_RULE = new ISchedulingRule() {
34 |
35 | /*
36 | * (non-Javadoc)
37 | *
38 | * @see
39 | * org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse
40 | * .core.runtime.jobs.ISchedulingRule)
41 | */
42 | public boolean contains(ISchedulingRule rule) {
43 | return rule == this;
44 | }
45 |
46 | /*
47 | * (non-Javadoc)
48 | *
49 | * @see
50 | * org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse
51 | * .core.runtime.jobs.ISchedulingRule)
52 | */
53 | public boolean isConflicting(ISchedulingRule rule) {
54 | return rule == this;
55 | }
56 |
57 | };
58 |
59 | class ContentLoader extends Job {
60 |
61 | private static final long IMAGE_LOAD_DELAY = 100;
62 | static final String JOB_FAMILY = "ContentLoader";
63 | private Object input;
64 | private Viewer viewer;
65 |
66 | public ContentLoader() {
67 | super("Image loading job");
68 | setSystem(true);
69 | setPriority(Job.INTERACTIVE);
70 | }
71 |
72 | @Override
73 | protected IStatus run(final IProgressMonitor monitor) {
74 | monitor.beginTask("loading image", 100);
75 | getJobManager().beginRule(CONTENT_LOADING_RULE, monitor);
76 | try {
77 | if (monitor.isCanceled())
78 | return Status.CANCEL_STATUS;
79 | disposeImage();
80 | monitor.worked(50);
81 | try {
82 | setImage(AbstractGraphicalContentProvider.this.loadImage(Display.getDefault(), getSuggestedSize(),
83 | input));
84 | } catch (CoreException e) {
85 | if (!e.getStatus().isOK())
86 | LogUtils.log(e.getStatus());
87 | setImage(createErrorImage(Display.getDefault(), getSuggestedSize(), e.getStatus()));
88 | }
89 | if (monitor.isCanceled())
90 | return Status.CANCEL_STATUS;
91 | monitor.worked(20);
92 | Display.getDefault().syncExec(new Runnable() {
93 | public void run() {
94 | if (monitor.isCanceled())
95 | return;
96 | monitor.worked(20);
97 | if (viewer != null)
98 | viewer.refresh();
99 | }
100 | });
101 | } finally {
102 | getJobManager().endRule(CONTENT_LOADING_RULE);
103 | monitor.done();
104 | }
105 | return Status.OK_STATUS;
106 | }
107 |
108 | public boolean belongsTo(Object family) {
109 | return JOB_FAMILY.equals(family);
110 | }
111 |
112 | private void asyncLoadImage(Object input, Viewer viewer) {
113 | // first cancel any competing image loading jobs
114 | getJobManager().cancel(JOB_FAMILY);
115 | this.input = input;
116 | if (viewer.getControl().isDisposed() || !viewer.getControl().isVisible())
117 | return;
118 | this.viewer = viewer;
119 | schedule(IMAGE_LOAD_DELAY);
120 | }
121 | }
122 |
123 | /*
124 | * (non-Javadoc)
125 | *
126 | * @see org.eclipse.jface.viewers.IContentProvider#dispose()
127 | */
128 | public void dispose() {
129 | this.loaderJob.cancel();
130 | disposeImage();
131 | }
132 |
133 | public void setImage(Image newImage) {
134 | disposeImage();
135 | this.image = newImage;
136 | }
137 |
138 | public Image createErrorImage(Display display, Point size, IStatus status) {
139 | Image errorImg = new Image(display, size.x, size.y);
140 | GC gc = new GC(errorImg);
141 | StringBuffer output = new StringBuffer("Errors generating an image.");
142 | if (!status.isOK())
143 | output.append("More details in the log file.");
144 | output.append("\n\n");
145 | gc.drawText(renderMessage(status, output), 10, 10);
146 | gc.dispose();
147 | return errorImg;
148 | }
149 |
150 | private String renderMessage(IStatus status, StringBuffer output) {
151 | output.append(status.getMessage());
152 | if (status.getException() != null)
153 | output.append("\n" + status.getException());
154 | for (IStatus child : status.getChildren()) {
155 | output.append("\n");
156 | renderMessage(child, output);
157 | }
158 | return output.toString();
159 | }
160 |
161 | private void disposeImage() {
162 | if (image == null)
163 | return;
164 | image.dispose();
165 | image = null;
166 | }
167 |
168 | public final Image getImage() {
169 | return image;
170 | }
171 |
172 | protected Point getSuggestedSize() {
173 | return suggestedSize;
174 | }
175 |
176 | public final void inputChanged(final Viewer viewer, Object oldInput, final Object newInput) {
177 | disposeImage();
178 | if (newInput != null)
179 | loaderJob.asyncLoadImage(newInput, viewer);
180 | }
181 |
182 | public void setSuggestedSize(Point suggestedSize) {
183 | this.suggestedSize = suggestedSize;
184 | }
185 |
186 | protected void reload() {
187 | this.loaderJob.schedule(200);
188 | }
189 |
190 | public abstract Image loadImage(Display display, Point suggestedSize, Object newInput) throws CoreException;
191 |
192 | /**
193 | * {@inheritDoc}
194 | *
195 | * This default implementation relies on the
196 | * {@link #loadImage(Display, Point, Object)} method, subclasses are
197 | * encouraged to provide a more efficient implementation.
198 | */
199 | public void saveImage(Display display, Point suggestedSize, Object input, IPath location, GraphicFileFormat fileFormat)
200 | throws CoreException {
201 | int swtFileFormat = getSWTFileFormat(fileFormat);
202 | Image toSave = loadImage(Display.getDefault(), new Point(0, 0), input);
203 | try {
204 | ImageLoader imageLoader = new ImageLoader();
205 | imageLoader.data = new ImageData[] { toSave.getImageData() };
206 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(200 * 1024);
207 | imageLoader.save(buffer, swtFileFormat);
208 | try {
209 | FileUtils.writeByteArrayToFile(location.toFile(), buffer.toByteArray());
210 | } catch (IOException e) {
211 | throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error saving image", e));
212 | }
213 | } finally {
214 | toSave.dispose();
215 | }
216 | }
217 |
218 | private int getSWTFileFormat(GraphicFileFormat fileFormat) {
219 | switch (fileFormat) {
220 | case BITMAP:
221 | return SWT.IMAGE_BMP;
222 | case GIF:
223 | return SWT.IMAGE_GIF;
224 | case JPEG:
225 | return SWT.IMAGE_JPEG;
226 | case TIFF:
227 | return SWT.IMAGE_TIFF;
228 | case PNG:
229 | default:
230 | return SWT.IMAGE_PNG;
231 | }
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/Activator.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import org.eclipse.core.runtime.Plugin;
4 | import org.osgi.framework.BundleContext;
5 |
6 | import com.abstratt.content.ContentSupport;
7 | import com.abstratt.pluginutils.LogUtils;
8 |
9 | /**
10 | * The activator class controls the plug-in life cycle
11 | */
12 | public class Activator extends Plugin {
13 |
14 | // The plug-in ID
15 | public static final String PLUGIN_ID = "com.abstratt.imageviewer";
16 |
17 | // The shared instance
18 | private static Activator plugin;
19 |
20 | /**
21 | * Returns the shared instance
22 | *
23 | * @return the shared instance
24 | */
25 | public static Activator getDefault() {
26 | return plugin;
27 | }
28 |
29 | public static void logUnexpected(String message, Exception e) {
30 | LogUtils.logError(ContentSupport.PLUGIN_ID, message, e);
31 | }
32 |
33 | /**
34 | * The constructor
35 | */
36 | public Activator() {
37 | }
38 |
39 | /*
40 | * (non-Javadoc)
41 | *
42 | * @see
43 | * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
44 | */
45 | @Override
46 | public void start(BundleContext context) throws Exception {
47 | super.start(context);
48 | plugin = this;
49 | }
50 |
51 | /*
52 | * (non-Javadoc)
53 | *
54 | * @see
55 | * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
56 | */
57 | @Override
58 | public void stop(BundleContext context) throws Exception {
59 | plugin = null;
60 | super.stop(context);
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/CopyToClipboardAction.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import org.eclipse.jface.action.IAction;
4 | import org.eclipse.jface.viewers.ISelection;
5 | import org.eclipse.swt.dnd.Clipboard;
6 | import org.eclipse.swt.dnd.ImageTransfer;
7 | import org.eclipse.swt.dnd.Transfer;
8 | import org.eclipse.swt.graphics.Image;
9 | import org.eclipse.swt.graphics.ImageData;
10 | import org.eclipse.swt.widgets.Display;
11 | import org.eclipse.ui.IViewActionDelegate;
12 | import org.eclipse.ui.IViewPart;
13 |
14 | public class CopyToClipboardAction implements IViewActionDelegate {
15 |
16 | private GraphicalView view;
17 |
18 | public void init(IViewPart view) {
19 | this.view = (GraphicalView) view;
20 | }
21 |
22 | public void run(IAction action) {
23 | Image image = view.getViewer().getImage();
24 | ImageData imageData = image.getImageData();
25 | ImageTransfer imageTransfer = ImageTransfer.getInstance();
26 | Clipboard clipboard = new Clipboard(Display.getCurrent());
27 | clipboard.setContents(new Object[] { imageData }, new Transfer[] { imageTransfer });
28 | }
29 |
30 | public void selectionChanged(IAction action, ISelection selection) {
31 | // don't care
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/DefaultGraphicalContentProvider.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.io.ByteArrayInputStream;
4 |
5 | import org.eclipse.swt.graphics.Image;
6 | import org.eclipse.swt.graphics.ImageData;
7 | import org.eclipse.swt.graphics.Point;
8 | import org.eclipse.swt.widgets.Display;
9 |
10 | public class DefaultGraphicalContentProvider extends AbstractGraphicalContentProvider {
11 |
12 | /*
13 | * (non-Javadoc)
14 | *
15 | * @see
16 | * com.abstratt.imageviewer.IGraphicalContentProvider#loadImage(org.eclipse
17 | * .swt.widgets.Display, org.eclipse.swt.graphics.Point, java.lang.Object)
18 | */
19 | public Image loadImage(Display display, Point suggestedSize, Object newInput) {
20 | ImageData imageData = new ImageData(new ByteArrayInputStream((byte[]) newInput));
21 | return new Image(display, imageData);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/FileToByteArrayContentReader.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import org.apache.commons.io.IOUtils;
8 | import org.eclipse.core.resources.IFile;
9 | import org.eclipse.core.runtime.CoreException;
10 |
11 | public class FileToByteArrayContentReader {
12 |
13 | public byte[] read(IFile input) {
14 | InputStream contents = null;
15 | try {
16 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
17 | contents = input.getContents();
18 | IOUtils.copy(contents, baos);
19 | return baos.toByteArray();
20 | } catch (IOException e) {
21 | Activator.logUnexpected(null, e);
22 | } catch (CoreException e) {
23 | Activator.logUnexpected(null, e);
24 | } finally {
25 | IOUtils.closeQuietly(contents);
26 | }
27 | return null;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/FileToURIReader.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.net.URI;
4 |
5 | import org.eclipse.core.resources.IFile;
6 |
7 | public class FileToURIReader {
8 | public URI read(IFile input) {
9 | return input.getLocationURI();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/GraphicalView.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import org.eclipse.core.resources.IFile;
4 | import org.eclipse.core.resources.IResourceChangeEvent;
5 | import org.eclipse.core.resources.IResourceChangeListener;
6 | import org.eclipse.core.resources.IResourceDelta;
7 | import org.eclipse.core.resources.ResourcesPlugin;
8 | import org.eclipse.core.runtime.CoreException;
9 | import org.eclipse.core.runtime.Platform;
10 | import org.eclipse.core.runtime.content.IContentDescription;
11 | import org.eclipse.jface.action.ActionContributionItem;
12 | import org.eclipse.jface.action.IAction;
13 | import org.eclipse.jface.action.IToolBarManager;
14 | import org.eclipse.jface.viewers.ISelection;
15 | import org.eclipse.jface.viewers.IStructuredSelection;
16 | import org.eclipse.swt.SWT;
17 | import org.eclipse.swt.widgets.Canvas;
18 | import org.eclipse.swt.widgets.Composite;
19 | import org.eclipse.swt.widgets.Display;
20 | import org.eclipse.ui.IEditorPart;
21 | import org.eclipse.ui.IPartListener2;
22 | import org.eclipse.ui.ISelectionListener;
23 | import org.eclipse.ui.IWorkbenchPart;
24 | import org.eclipse.ui.IWorkbenchPartReference;
25 | import org.eclipse.ui.part.ViewPart;
26 |
27 | import com.abstratt.content.ContentSupport;
28 | import com.abstratt.content.IContentProviderRegistry.IProviderDescription;
29 |
30 | /**
31 | * A view that wraps a {@link GraphicalViewer}.
32 | */
33 | public class GraphicalView extends ViewPart implements IResourceChangeListener, IPartListener2, ISelectionListener {
34 | public final static String VIEW_ID = "com.abstratt.imageviewer.GraphicalView";
35 | private Canvas canvas;
36 | private GraphicalViewer viewer;
37 | private String basePartName;
38 | private IFile selectedFile;
39 | private IProviderDescription providerDefinition;
40 | /**
41 | * Whether this view should try to automatically react to changes in
42 | * selection/selected object.
43 | */
44 | private boolean autoSync = true;
45 |
46 | /**
47 | * The constructor.
48 | */
49 | public GraphicalView() {
50 | //
51 | }
52 |
53 | public GraphicalViewer getViewer() {
54 | return viewer;
55 | };
56 |
57 | /**
58 | * This is a callback that will allow us to create the viewer and initialize
59 | * it.
60 | */
61 | @Override
62 | public void createPartControl(Composite parent) {
63 | basePartName = getPartName();
64 | canvas = new Canvas(parent, SWT.NONE);
65 | viewer = new GraphicalViewer(canvas);
66 | installResourceListener();
67 | installSelectionListener();
68 | installPartListener();
69 | }
70 |
71 | @Override
72 | public void dispose() {
73 | ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
74 | getSite().getPage().removePartListener(this);
75 | getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
76 | super.dispose();
77 | }
78 |
79 | private void installPartListener() {
80 | getSite().getPage().addPartListener(this);
81 | // tries to load an image for the current active part, if any
82 | loadFromActivePart();
83 | }
84 |
85 | private void loadFromActivePart() {
86 | final IWorkbenchPartReference activePartReference = getSite().getPage().getActivePartReference();
87 | if (activePartReference != null)
88 | reactToPartChange(activePartReference);
89 | }
90 |
91 | private void installResourceListener() {
92 | ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
93 | }
94 |
95 | private void installSelectionListener() {
96 | getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
97 | }
98 |
99 | public void selectionChanged(IWorkbenchPart part, ISelection selection) {
100 | reactToSelection(selection);
101 | }
102 |
103 | private void reactToSelection(ISelection selection) {
104 | if (!autoSync)
105 | return;
106 | if (!(selection instanceof IStructuredSelection))
107 | return;
108 | IStructuredSelection structured = (IStructuredSelection) selection;
109 | if (structured.size() != 1)
110 | return;
111 | Object selected = structured.getFirstElement();
112 | IFile file = (IFile) Platform.getAdapterManager().getAdapter(selected, IFile.class);
113 | reload(file);
114 | }
115 |
116 | public void partActivated(IWorkbenchPartReference partRef) {
117 | reactToPartChange(partRef);
118 | }
119 |
120 | public void partBroughtToTop(IWorkbenchPartReference partRef) {
121 | reactToPartChange(partRef);
122 | }
123 |
124 | public void partClosed(IWorkbenchPartReference partRef) {
125 | //
126 | }
127 |
128 | public void partDeactivated(IWorkbenchPartReference partRef) {
129 | //
130 | }
131 |
132 | public void partHidden(IWorkbenchPartReference partRef) {
133 | //
134 | }
135 |
136 | public void partInputChanged(IWorkbenchPartReference partRef) {
137 | reactToPartChange(partRef);
138 | }
139 |
140 | public void partOpened(IWorkbenchPartReference partRef) {
141 | reactToPartChange(partRef);
142 | }
143 |
144 | public void partVisible(IWorkbenchPartReference partRef) {
145 | reactToPartChange(partRef);
146 | }
147 |
148 | private void reactToPartChange(IWorkbenchPartReference part) {
149 | if (!autoSync)
150 | return;
151 | if (!(part.getPart(false) instanceof IEditorPart))
152 | return;
153 | IEditorPart editorPart = (IEditorPart) part.getPart(false);
154 | if (!getViewSite().getPage().isPartVisible(editorPart))
155 | return;
156 | IGraphicalFileProvider graphicalSource = (IGraphicalFileProvider) editorPart
157 | .getAdapter(IGraphicalFileProvider.class);
158 | if (graphicalSource != null)
159 | selectedFile = graphicalSource.getGraphicalFile();
160 | else
161 | selectedFile = null;
162 | if (selectedFile == null) {
163 | IFile asFile = (IFile) editorPart.getAdapter(IFile.class);
164 | if (asFile == null)
165 | asFile = (IFile) editorPart.getEditorInput().getAdapter(IFile.class);
166 | if (asFile == null)
167 | return;
168 | selectedFile = asFile;
169 | }
170 | requestUpdate();
171 | }
172 |
173 | private void reload(IFile file) {
174 | setPartName(basePartName);
175 | this.providerDefinition = null;
176 | this.selectedFile = null;
177 | if (file == null || !file.exists())
178 | return;
179 | if (viewer.getContentProvider() != null)
180 | // to avoid one provider trying to interpret an
181 | // incompatible input
182 | viewer.setInput(null);
183 | IContentDescription contentDescription = null;
184 | try {
185 | contentDescription = file.getContentDescription();
186 | } catch (CoreException e) {
187 | if (Platform.inDebugMode())
188 | Activator.logUnexpected(null, e);
189 | }
190 | if (contentDescription == null || contentDescription.getContentType() == null)
191 | return;
192 | IProviderDescription providerDefinition = ContentSupport.getContentProviderRegistry().findContentProvider(
193 | contentDescription.getContentType(), IGraphicalContentProvider.class);
194 | if (providerDefinition == null) {
195 | return;
196 | }
197 | IGraphicalContentProvider provider = (IGraphicalContentProvider) providerDefinition.getProvider();
198 | setContents(providerDefinition.read(file), provider);
199 | // enables support for file rendering
200 | this.selectedFile = file;
201 | this.providerDefinition = providerDefinition;
202 | setPartName(basePartName + " - " + file.getName());
203 | }
204 |
205 | /**
206 | * Force feeds the contents to be shown.
207 | *
208 | * @param contents
209 | * the contents to be presented (as expected by the content
210 | * provider
211 | * @param provider
212 | * the graphical content provider that can render the given
213 | * contents
214 | */
215 | public void setContents(Object contents, IGraphicalContentProvider provider) {
216 | // assumes the general case (instead of file rendering)
217 | selectedFile = null;
218 | providerDefinition = null;
219 | viewer.setContentProvider(provider);
220 | viewer.setInput(contents);
221 | setPartName(basePartName);
222 | }
223 |
224 | Object getInput() {
225 | return viewer.getInput();
226 | }
227 |
228 | IGraphicalContentProvider getContentProvider() {
229 | return (IGraphicalContentProvider) viewer.getContentProvider();
230 | }
231 |
232 | private void requestUpdate() {
233 | Display.getDefault().asyncExec(new Runnable() {
234 | public void run() {
235 | if (getSite() == null || !GraphicalView.this.getSite().getPage().isPartVisible(GraphicalView.this))
236 | // don't do anything if we are not showing
237 | return;
238 | reload(selectedFile);
239 | }
240 | });
241 | }
242 |
243 | public void resourceChanged(IResourceChangeEvent event) {
244 | if (selectedFile == null || !selectedFile.exists())
245 | return;
246 | if (event.getDelta() == null)
247 | return;
248 | IResourceDelta interestingChange = event.getDelta().findMember(selectedFile.getFullPath());
249 | if (interestingChange != null)
250 | requestUpdate();
251 | }
252 |
253 | /**
254 | * Passing the focus request to the viewer's control.
255 | */
256 | @Override
257 | public void setFocus() {
258 | viewer.getControl().setFocus();
259 | }
260 |
261 | public IProviderDescription getContentProviderDescription() {
262 | return providerDefinition;
263 | }
264 |
265 | public IFile getSelectedFile() {
266 | return selectedFile;
267 | }
268 |
269 | public boolean isAutoSync() {
270 | return autoSync;
271 | }
272 |
273 | /**
274 | * Enables/disables the view auto-sync feature.
275 | *
276 | * @param autoSync
277 | * whether the view should auto synchronize to the current
278 | * selection.
279 | */
280 | public void setAutoSync(boolean autoSync) {
281 | this.autoSync = autoSync;
282 | updateAutoSyncToggleButtonState();
283 | }
284 |
285 | private void updateAutoSyncToggleButtonState() {
286 | IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
287 | ActionContributionItem autoSyncToggleContribution = (ActionContributionItem) toolBarManager
288 | .find("com.abstratt.imageviewer.autoUpdate");
289 | if (autoSyncToggleContribution != null) {
290 | IAction action = autoSyncToggleContribution.getAction();
291 | action.setChecked(isAutoSync());
292 | }
293 | }
294 |
295 | /**
296 | * Toggles the view auto-sync state.
297 | */
298 | public void toggleSync() {
299 | setAutoSync(!isAutoSync());
300 | }
301 | }
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/GraphicalViewer.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 |
5 | import org.apache.commons.beanutils.ConstructorUtils;
6 | import org.eclipse.jface.viewers.ContentViewer;
7 | import org.eclipse.jface.viewers.IContentProvider;
8 | import org.eclipse.jface.viewers.ISelection;
9 | import org.eclipse.swt.SWT;
10 | import org.eclipse.swt.events.PaintEvent;
11 | import org.eclipse.swt.events.PaintListener;
12 | import org.eclipse.swt.graphics.GC;
13 | import org.eclipse.swt.graphics.Image;
14 | import org.eclipse.swt.graphics.Point;
15 | import org.eclipse.swt.graphics.Rectangle;
16 | import org.eclipse.swt.widgets.Canvas;
17 | import org.eclipse.swt.widgets.Composite;
18 | import org.eclipse.swt.widgets.Control;
19 | import org.eclipse.swt.widgets.Event;
20 | import org.eclipse.swt.widgets.Listener;
21 |
22 | /**
23 | * A viewer that knows how to display graphical contents.
24 | *
25 | * @see IGraphicalContentProvider
26 | */
27 | public class GraphicalViewer extends ContentViewer {
28 |
29 | private Canvas canvas;
30 |
31 | private boolean adjustToCanvas = true;
32 |
33 | private boolean imageRedrawRequested;
34 |
35 | public GraphicalViewer(Composite parent) {
36 | canvas = new Canvas(parent, SWT.NONE);
37 | parent.addListener(SWT.Resize, new Listener() {
38 | public void handleEvent(Event event) {
39 | canvas.setBounds(canvas.getParent().getClientArea());
40 | requestImageRedraw();
41 | }
42 | });
43 | canvas.addPaintListener(new PaintListener() {
44 | public void paintControl(PaintEvent e) {
45 | redrawImageIfRequested();
46 | GC gc = e.gc;
47 | paintCanvas(gc);
48 | }
49 |
50 | });
51 | }
52 |
53 | public Canvas getCanvas() {
54 | return canvas;
55 | }
56 |
57 | @Override
58 | public Control getControl() {
59 | return canvas;
60 | }
61 |
62 | private Rectangle getDrawingBounds(Image image) {
63 | Rectangle imageBounds = image.getBounds();
64 | Rectangle canvasBounds = canvas.getBounds();
65 |
66 | double hScale = (double) canvasBounds.width / imageBounds.width;
67 | double vScale = (double) canvasBounds.height / imageBounds.height;
68 |
69 | double scale = Math.min(1, Math.min(hScale, vScale));
70 |
71 | int width = (int) (imageBounds.width * scale);
72 | int height = (int) (imageBounds.height * scale);
73 |
74 | int x = (canvasBounds.width - width) / 2;
75 | int y = (canvasBounds.height - height) / 2;
76 |
77 | return new Rectangle(x, y, width, height);
78 | }
79 |
80 | private Image getImage(Point point) {
81 | IGraphicalContentProvider provider = (IGraphicalContentProvider) getContentProvider();
82 | if (provider == null)
83 | return null;
84 | return provider.getImage();
85 | }
86 |
87 | @Override
88 | public ISelection getSelection() {
89 | // no selection supported
90 | return null;
91 | }
92 |
93 | @Override
94 | protected void inputChanged(Object newInput, Object oldInput) {
95 | refresh();
96 | }
97 |
98 | public boolean isAdjustToCanvas() {
99 | return adjustToCanvas;
100 | }
101 |
102 | private void paintCanvas(GC gc) {
103 | Image image = getImage();
104 | if (image == null || image.isDisposed())
105 | return;
106 | Rectangle drawingBounds = getDrawingBounds(image);
107 | gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, drawingBounds.x, drawingBounds.y,
108 | drawingBounds.width, drawingBounds.height);
109 | }
110 |
111 | public Image getImage() {
112 | return getImage(canvas.getSize());
113 | }
114 |
115 | public void redrawImage() {
116 | if (getContentProvider() == null)
117 | return;
118 | Class> contentProviderClass = getContentProvider().getClass();
119 | try {
120 | setContentProvider((IContentProvider) ConstructorUtils.invokeConstructor(contentProviderClass,
121 | new Object[0]));
122 | } catch (NoSuchMethodException e) {
123 | Activator.logUnexpected(null, e);
124 | } catch (IllegalAccessException e) {
125 | Activator.logUnexpected(null, e);
126 | } catch (InvocationTargetException e) {
127 | Activator.logUnexpected(null, e);
128 | } catch (InstantiationException e) {
129 | Activator.logUnexpected(null, e);
130 | }
131 | }
132 |
133 | protected void redrawImageIfRequested() {
134 | if (imageRedrawRequested)
135 | redrawImage();
136 | imageRedrawRequested = false;
137 | }
138 |
139 | @Override
140 | public void refresh() {
141 | if (!canvas.isDisposed())
142 | canvas.redraw();
143 | }
144 |
145 | private void requestImageRedraw() {
146 | imageRedrawRequested = true;
147 | }
148 |
149 | public void setAdjustToCanvas(boolean adjustToCanvas) {
150 | this.adjustToCanvas = adjustToCanvas;
151 | requestImageRedraw();
152 | }
153 |
154 | @Override
155 | public void setContentProvider(IContentProvider contentProvider) {
156 | if (contentProvider != null) {
157 | if (!(contentProvider instanceof IGraphicalContentProvider))
158 | throw new IllegalArgumentException(IGraphicalContentProvider.class.getName());
159 | if (adjustToCanvas && !canvas.isDisposed())
160 | ((IGraphicalContentProvider) contentProvider).setSuggestedSize(canvas.getSize());
161 | }
162 | super.setContentProvider(contentProvider);
163 | }
164 |
165 | @Override
166 | public void setSelection(ISelection selection, boolean reveal) {
167 | throw new UnsupportedOperationException();
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/IGraphicalContentProvider.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.util.Arrays;
4 | import java.util.EnumSet;
5 | import java.util.Set;
6 |
7 | import org.eclipse.core.runtime.CoreException;
8 | import org.eclipse.core.runtime.IPath;
9 | import org.eclipse.jface.viewers.IContentProvider;
10 | import org.eclipse.swt.graphics.Image;
11 | import org.eclipse.swt.graphics.Point;
12 | import org.eclipse.swt.widgets.Display;
13 | import static com.abstratt.imageviewer.IGraphicalContentProvider.GraphicFileFormat.*;
14 | /**
15 | * A content provider that can render a graphical output.
16 | */
17 | public interface IGraphicalContentProvider extends IContentProvider {
18 | /**
19 | * Returns this provider's current image.
20 | *
21 | * @param suggestedDimension
22 | *
23 | * @throws IllegalStateException
24 | * if no input has been set
25 | * @return the rendered image
26 | */
27 | public Image getImage();
28 |
29 | public void setSuggestedSize(Point suggested);
30 |
31 | /**
32 | * Returns an image produced from the given input. This method might be
33 | * invoked from a non-UI thread.
34 | *
35 | * @param display
36 | * @param suggestedSize
37 | * @param newInput
38 | * @return the image loaded
39 | * @throws CoreException
40 | * if an error occurs while producing the image
41 | */
42 | public Image loadImage(Display display, Point suggestedSize, Object newInput) throws CoreException;
43 |
44 | /**
45 | * Generates an image at the given location.
46 | *
47 | * @param display
48 | * @param suggestedSize
49 | * @param input
50 | * @param location
51 | * @throws CoreException
52 | */
53 | public void saveImage(Display display, Point suggestedSize, Object input, IPath location, GraphicFileFormat fileFormat)
54 | throws CoreException;
55 |
56 | enum GraphicFileFormat {
57 | JPEG("jpg"), PNG("png"), GIF("gif"), TIFF("tif"), BITMAP("bmp"), SVG("svg"), DOT("dot");
58 | String extension;
59 | GraphicFileFormat(String extension) {
60 | this.extension = extension;
61 | }
62 | public static GraphicFileFormat byExtension(String toMatch) {
63 | return Arrays.stream(values()).filter(it -> it.extension.equals(toMatch)).findAny().orElse(null);
64 | }
65 | public String getExtension() {
66 | return extension;
67 | }
68 | }
69 |
70 | default Set getSupportedFormats() {
71 | return EnumSet.of(BITMAP, GIF, TIFF, JPEG, PNG);
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/IGraphicalFileProvider.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import org.eclipse.core.resources.IFile;
4 |
5 | /**
6 | * This interface should be implemented by adaptable objects that correspond to
7 | * a file containing graphical contents.
8 | */
9 | public interface IGraphicalFileProvider {
10 | public IFile getGraphicalFile();
11 | }
12 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/SaveToFileAction.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import java.io.File;
4 |
5 | import org.eclipse.core.resources.IFile;
6 | import org.eclipse.core.runtime.CoreException;
7 | import org.eclipse.core.runtime.IPath;
8 | import org.eclipse.core.runtime.IProgressMonitor;
9 | import org.eclipse.core.runtime.IStatus;
10 | import org.eclipse.core.runtime.Path;
11 | import org.eclipse.core.runtime.Status;
12 | import org.eclipse.core.runtime.jobs.Job;
13 | import org.eclipse.jface.action.IAction;
14 | import org.eclipse.jface.dialogs.MessageDialog;
15 | import org.eclipse.jface.viewers.ISelection;
16 | import org.eclipse.swt.SWT;
17 | import org.eclipse.swt.graphics.Point;
18 | import org.eclipse.swt.widgets.Display;
19 | import org.eclipse.swt.widgets.FileDialog;
20 | import org.eclipse.ui.IViewActionDelegate;
21 | import org.eclipse.ui.IViewPart;
22 |
23 | import com.abstratt.content.IContentProviderRegistry.IProviderDescription;
24 | import com.abstratt.content.PlaceholderProviderDescription;
25 | import com.abstratt.imageviewer.IGraphicalContentProvider.GraphicFileFormat;
26 |
27 | public class SaveToFileAction implements IViewActionDelegate {
28 |
29 | private GraphicalView view;
30 |
31 | public void init(IViewPart view) {
32 | this.view = (GraphicalView) view;
33 | }
34 |
35 | public void run(IAction action) {
36 | IProviderDescription providerDefinition = view.getContentProviderDescription();
37 | IGraphicalContentProvider contentProvider = view.getContentProvider();
38 | if (providerDefinition == null)
39 | providerDefinition = new PlaceholderProviderDescription(view.getInput(), contentProvider);
40 |
41 | IFile selectedFile = view.getSelectedFile();
42 | String suggestedName;
43 | if (selectedFile == null)
44 | suggestedName = "image";
45 | else
46 | suggestedName = selectedFile.getLocation().removeFileExtension().lastSegment();
47 | boolean pathIsValid = false;
48 | IPath path = null;
49 | GraphicFileFormat fileFormat = null;
50 | while (!pathIsValid) {
51 | FileDialog saveDialog = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE);
52 | saveDialog.setText("Choose a location to save to");
53 | saveDialog.setFileName(suggestedName);
54 | saveDialog.setFilterExtensions(contentProvider.getSupportedFormats().stream().map(it -> "*." + it.getExtension()).toArray(s -> new String[s]));
55 | String pathString = saveDialog.open();
56 | if (pathString == null)
57 | return;
58 | path = Path.fromOSString(pathString);
59 | if (path.toFile().isDirectory()) {
60 | MessageDialog.openError(null, "Invalid file path", "Location is already in use by a directory");
61 | continue;
62 | }
63 | fileFormat = GraphicFileFormat.byExtension(path.getFileExtension());
64 | if (fileFormat == null) {
65 | MessageDialog.openError(null, "Invalid file extension", "Supported file formats are: "
66 | + contentProvider.getSupportedFormats().toString());
67 | continue;
68 | }
69 | File parentDir = path.toFile().getParentFile();
70 | parentDir.mkdirs();
71 | if (parentDir.isDirectory())
72 | pathIsValid = true;
73 | else
74 | MessageDialog.openError(null, "Invalid file path", "Could not create directory");
75 | }
76 |
77 | new SaveImageJob(fileFormat, path, providerDefinition).schedule();
78 | }
79 |
80 | private class SaveImageJob extends Job {
81 |
82 | private IProviderDescription providerDefinition;
83 | private IPath path;
84 | private GraphicFileFormat fileFormat;
85 |
86 | public SaveImageJob(GraphicFileFormat fileFormat, IPath path, IProviderDescription providerDefinition) {
87 | super("Image saving job");
88 | this.fileFormat = fileFormat;
89 | this.path = path;
90 | this.providerDefinition = providerDefinition;
91 | }
92 |
93 | @Override
94 | protected IStatus run(IProgressMonitor monitor) {
95 | monitor.beginTask("saving image", 100);
96 | getJobManager().beginRule(AbstractGraphicalContentProvider.CONTENT_LOADING_RULE, monitor);
97 | try {
98 | IGraphicalContentProvider provider = (IGraphicalContentProvider) providerDefinition.getProvider();
99 | Object input = providerDefinition.read(view.getSelectedFile());
100 | provider.saveImage(Display.getDefault(), new Point(0, 0), input, path, fileFormat);
101 | } catch (CoreException e) {
102 | return e.getStatus();
103 | } finally {
104 | getJobManager().endRule(AbstractGraphicalContentProvider.CONTENT_LOADING_RULE);
105 | monitor.done();
106 | }
107 | return Status.OK_STATUS;
108 | }
109 | }
110 |
111 | public void selectionChanged(IAction action, ISelection selection) {
112 | // don't care
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.imageviewer/src/com/abstratt/imageviewer/ToggleSyncAction.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.imageviewer;
2 |
3 | import org.eclipse.jface.action.IAction;
4 | import org.eclipse.jface.viewers.ISelection;
5 | import org.eclipse.ui.IViewActionDelegate;
6 | import org.eclipse.ui.IViewPart;
7 |
8 | public class ToggleSyncAction implements IViewActionDelegate {
9 |
10 | private GraphicalView view;
11 |
12 | public void init(IViewPart view) {
13 | this.view = (GraphicalView) view;
14 | }
15 |
16 | public void run(IAction action) {
17 | this.view.toggleSync();
18 | }
19 |
20 | public void selectionChanged(IAction action, ISelection selection) {
21 | // don't care
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.abstratt.pluginutils
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.pde.ManifestBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.pde.SchemaBuilder
20 |
21 |
22 |
23 |
24 | org.eclipse.m2e.core.maven2Builder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.m2e.core.maven2Nature
31 | org.eclipse.pde.PluginNature
32 | org.eclipse.jdt.core.javanature
33 |
34 |
35 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Bundle-ManifestVersion: 2
3 | Bundle-Name: Plug-in Utils
4 | Bundle-SymbolicName: com.abstratt.pluginutils
5 | Bundle-Version: 2.13.0
6 | Bundle-Vendor: Abstratt Technologies
7 | Require-Bundle: org.eclipse.core.runtime
8 | Export-Package: com.abstratt.pluginutils
9 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8
10 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/build.properties:
--------------------------------------------------------------------------------
1 | source.. = src/
2 | output.. = bin/
3 | bin.includes = META-INF/,\
4 | .
5 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.abstratt.eclipsegraphviz
6 | com.abstratt.pluginutils
7 | 2.13.0
8 | eclipse-plugin
9 |
10 | com.abstratt.eclipsegraphviz.parent
11 | com.abstratt.eclipsegraphviz
12 | 2.13.0
13 | ../..
14 |
15 |
16 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/ConfigUtils.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.pluginutils;
2 |
3 | public class ConfigUtils {
4 | public static String get(String name) {
5 | return get(name, null);
6 | }
7 |
8 | public static String get(String name, String defaultValue) {
9 | String asProperty = System.getProperty(name);
10 | if (asProperty != null)
11 | return asProperty;
12 | String asEnvVar = System.getenv(name);
13 | if (asEnvVar != null)
14 | return asEnvVar;
15 | return defaultValue;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/ISharedContextRunnable.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.pluginutils;
2 |
3 | /**
4 | * A runnable that does not need to make changes.
5 | */
6 | public interface ISharedContextRunnable {
7 | public R runInContext(C context);
8 | }
9 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.pluginutils;
2 |
3 | import java.util.function.Supplier;
4 |
5 | import org.eclipse.core.runtime.IStatus;
6 | import org.eclipse.core.runtime.Platform;
7 | import org.eclipse.core.runtime.Status;
8 | import org.osgi.framework.Bundle;
9 |
10 | public class LogUtils {
11 | public static void log(int severity, String pluginId, Supplier message, Throwable exception) {
12 | log(() -> new Status(severity, pluginId, message.get(), exception));
13 | }
14 |
15 | public static void log(int severity, String pluginId, String message, Throwable exception) {
16 | log(() -> new Status(severity, pluginId, message, exception));
17 | }
18 |
19 | public static void log(IStatus status) {
20 | log(() -> status);
21 | }
22 | public static void log(Supplier statusSupplier) {
23 | IStatus status = statusSupplier.get();
24 | if (!Platform.isRunning()) {
25 | System.err.println(status.getMessage());
26 | if (status.getException() != null)
27 | status.getException().printStackTrace();
28 | if (status.isMultiStatus())
29 | for (IStatus child : status.getChildren())
30 | log(child);
31 | return;
32 | }
33 | Bundle bundle = Platform.getBundle(status.getPlugin());
34 | if (bundle == null) {
35 | String thisPluginId = LogUtils.class.getPackage().getName();
36 | bundle = Platform.getBundle(thisPluginId);
37 | Platform.getLog(bundle).log(
38 | new Status(IStatus.WARNING, thisPluginId, "Could not find a plugin " + status.getPlugin()
39 | + " for logging as"));
40 | }
41 | Platform.getLog(bundle).log(status);
42 | }
43 |
44 | public static void logError(String pluginId, String message, Throwable e) {
45 | log(IStatus.ERROR, pluginId, message, e);
46 | }
47 |
48 | public static void logWarning(String pluginId, String message, Throwable e) {
49 | log(IStatus.WARNING, pluginId, message, e);
50 | }
51 |
52 | public static void logInfo(String pluginId, String message, Throwable e) {
53 | log(IStatus.INFO, pluginId, message, e);
54 | }
55 |
56 | public static void debug(String pluginId, String message) {
57 | debug(pluginId, () -> message);
58 | }
59 |
60 | public static void debug(String pluginId, Supplier message) {
61 | if (Boolean.getBoolean(pluginId + ".debug"))
62 | log(IStatus.INFO, pluginId, message.get(), null);
63 | }
64 |
65 | public static void logError(Class pluginClass, String message, Throwable e) {
66 | logError(pluginClass.getPackage().getName(), message, e);
67 | }
68 |
69 | public static void logWarning(Class pluginClass, String message, Throwable e) {
70 | logWarning(pluginClass.getPackage().getName(), message, e);
71 | }
72 |
73 | public static void logInfo(Class pluginClass, String message, Throwable e) {
74 | logInfo(pluginClass.getPackage().getName(), message, e);
75 | }
76 |
77 | public static void debug(Class pluginClass, String message) {
78 | debug(pluginClass.getName(), () -> message);
79 | }
80 |
81 | public static void debug(Class pluginClass, Supplier message) {
82 | debug(pluginClass.getName(), message);
83 | }
84 |
85 | public static void log(int severity, Class pluginClass, Supplier message, Throwable exception) {
86 | log(severity, pluginClass.getPackage().getName(), message, exception);
87 | }
88 |
89 | public static void log(int severity, Class pluginClass, String message, Throwable exception) {
90 | log(severity, pluginClass.getPackage().getName(), message, exception);
91 | }
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/NodeSorter.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.pluginutils;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public class NodeSorter {
10 | public interface NodeHandler {
11 | Collection next(T node);
12 | }
13 |
14 | static class Counter {
15 | int count = 0;
16 |
17 | @Override
18 | public String toString() {
19 | return "" + count;
20 | }
21 | }
22 |
23 | public static List sort(Collection toSort, NodeHandler nodeHandler) {
24 | if (toSort.size() < 2)
25 | return new ArrayList(toSort);
26 | Map predecessorCounts = new HashMap(toSort.size());
27 | for (N vertex : toSort)
28 | predecessorCounts.put(vertex, new Counter());
29 | for (N vertex : toSort) {
30 | Collection successors = nodeHandler.next(vertex);
31 | for (N successor : successors) {
32 | Counter predecessorCount = predecessorCounts.get(successor);
33 | if (predecessorCount != null)
34 | predecessorCount.count++;
35 | }
36 | }
37 | List sorted = new ArrayList(toSort.size());
38 | for (int i = 0; i < toSort.size(); i++)
39 | for (Map.Entry it : predecessorCounts.entrySet())
40 | if (it.getValue().count == 0) {
41 | it.getValue().count = -1;
42 | sorted.add(it.getKey());
43 | if (sorted.size() == toSort.size())
44 | return sorted;
45 | for (N successor : nodeHandler.next(it.getKey())) {
46 | Counter predecessorCount = predecessorCounts.get(successor);
47 | if (predecessorCount != null)
48 | predecessorCount.count--;
49 | }
50 | }
51 | throw new IllegalArgumentException("Cycle found");
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/RegistryReader.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2000, 2007 IBM Corporation and others.
3 | * All rights reserved. This program and the accompanying materials
4 | * are made available under the terms of the Eclipse Public License v1.0
5 | * which accompanies this distribution, and is available at
6 | * http://www.eclipse.org/legal/epl-v10.html
7 | *
8 | * Contributors:
9 | * IBM Corporation - initial API and implementation
10 | *******************************************************************************/
11 | package com.abstratt.pluginutils;
12 |
13 | import java.util.Arrays;
14 | import java.util.Comparator;
15 |
16 | import org.eclipse.core.runtime.IConfigurationElement;
17 | import org.eclipse.core.runtime.IExtension;
18 | import org.eclipse.core.runtime.IExtensionPoint;
19 | import org.eclipse.core.runtime.IExtensionRegistry;
20 |
21 | /**
22 | * Template implementation of a registry reader that creates objects
23 | * representing registry contents. Typically, an extension contains one element,
24 | * but this reader handles multiple elements per extension.
25 | *
26 | * To start reading the extensions from the registry for an extension point,
27 | * call the method readRegistry
.
28 | *
29 | * To read children of an IConfigurationElement, call the method
30 | * readElementChildren
from your implementation of the method
31 | * readElement
, as it will not be done by default.
32 | */
33 | public abstract class RegistryReader {
34 |
35 | public static final String ATT_CLASS = "class"; //$NON-NLS-1$
36 |
37 | /**
38 | * Utility for extracting the value of a class attribute or a nested class
39 | * element that follows the pattern set forth by
40 | * {@link org.eclipse.core.runtime.IExecutableExtension}.
41 | *
42 | * @param configElement
43 | * the element
44 | * @param classAttributeName
45 | * the name of the class attribute to check
46 | * @return the value of the attribute or nested class element
47 | * @since 3.1
48 | */
49 | public static String getClassValue(IConfigurationElement configElement, String classAttributeName) {
50 | String className = configElement.getAttribute(classAttributeName);
51 | if (className != null) {
52 | return className;
53 | }
54 | IConfigurationElement[] candidateChildren = configElement.getChildren(classAttributeName);
55 | if (candidateChildren.length == 0) {
56 | return null;
57 | }
58 |
59 | return candidateChildren[0].getAttribute(ATT_CLASS);
60 | }
61 |
62 | /**
63 | * Apply a reproducable order to the list of extensions provided, such that
64 | * the order will not change as extensions are added or removed.
65 | *
66 | * @param extensions
67 | * the extensions to order
68 | * @return ordered extensions
69 | */
70 | public static IExtension[] orderExtensions(IExtension[] extensions) {
71 | // By default, the order is based on plugin id sorted
72 | // in ascending order. The order for a plugin providing
73 | // more than one extension for an extension point is
74 | // dependent in the order listed in the XML file.
75 | IExtension[] sortedExtension = new IExtension[extensions.length];
76 | System.arraycopy(extensions, 0, sortedExtension, 0, extensions.length);
77 | Comparator comparer = new Comparator() {
78 | public int compare(IExtension e1, IExtension e2) {
79 | return e1.getNamespaceIdentifier().compareToIgnoreCase(e2.getNamespaceIdentifier());
80 | }
81 | };
82 | Arrays.sort(sortedExtension, comparer);
83 | return sortedExtension;
84 | }
85 |
86 | protected abstract String getNamespace();
87 |
88 | /**
89 | * Logs the error in the workbench log using the provided text and the
90 | * information in the configuration element.
91 | */
92 | protected void logError(IConfigurationElement element, String text) {
93 | IExtension extension = element.getDeclaringExtension();
94 | StringBuffer buf = new StringBuffer();
95 | buf.append("Plugin " + extension.getContributor().getName() + ", extension " + extension.getExtensionPointUniqueIdentifier());//$NON-NLS-2$//$NON-NLS-1$
96 | buf.append("\n" + text);//$NON-NLS-1$
97 | LogUtils.logError(getNamespace(), buf.toString(), null);
98 | }
99 |
100 | /**
101 | * Logs a very common registry error when a required attribute is missing.
102 | */
103 | protected void logMissingAttribute(IConfigurationElement element, String attributeName) {
104 | logError(element, "Required attribute '" + attributeName + "' not defined");//$NON-NLS-2$//$NON-NLS-1$
105 | }
106 |
107 | /**
108 | * Logs a very common registry error when a required child is missing.
109 | */
110 | protected void logMissingElement(IConfigurationElement element, String elementName) {
111 | logError(element, "Required sub element '" + elementName + "' not defined");//$NON-NLS-2$//$NON-NLS-1$
112 | }
113 |
114 | /**
115 | * Logs a registry error when the configuration element is unknown.
116 | */
117 | protected void logUnknownElement(IConfigurationElement element) {
118 | logError(element, "Unknown extension tag found: " + element.getName());//$NON-NLS-1$
119 | }
120 |
121 | /**
122 | * Implement this method to read element's attributes. If children should
123 | * also be read, then implementor is responsible for calling
124 | * readElementChildren
. Implementor is also responsible for
125 | * logging missing attributes.
126 | *
127 | * @return true if element was recognized, false if not.
128 | */
129 | protected abstract boolean readElement(IConfigurationElement element);
130 |
131 | /**
132 | * Read the element's children. This is called by the subclass' readElement
133 | * method when it wants to read the children of the element.
134 | */
135 | protected void readElementChildren(IConfigurationElement element) {
136 | readElements(element.getChildren());
137 | }
138 |
139 | /**
140 | * Read each element one at a time by calling the subclass implementation of
141 | * readElement
.
142 | *
143 | * Logs an error if the element was not recognized.
144 | */
145 | protected void readElements(IConfigurationElement[] elements) {
146 | for (int i = 0; i < elements.length; i++) {
147 | if (!readElement(elements[i])) {
148 | logUnknownElement(elements[i]);
149 | }
150 | }
151 | }
152 |
153 | /**
154 | * Read one extension by looping through its configuration elements.
155 | */
156 | protected void readExtension(IExtension extension) {
157 | readElements(extension.getConfigurationElements());
158 | }
159 |
160 | /**
161 | * Start the registry reading process using the supplied plugin ID and
162 | * extension point.
163 | *
164 | * @param registry
165 | * the registry to read from
166 | * @param extensionPoint
167 | * the fully qualified extension point id
168 | */
169 | public void readRegistry(IExtensionRegistry registry, String extensionPoint) {
170 | IExtensionPoint point = registry.getExtensionPoint(extensionPoint);
171 | if (point == null) {
172 | return;
173 | }
174 | IExtension[] extensions = point.getExtensions();
175 | extensions = orderExtensions(extensions);
176 | for (int i = 0; i < extensions.length; i++) {
177 | readExtension(extensions[i]);
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/plugins/com.abstratt.pluginutils/src/com/abstratt/pluginutils/UserFacingException.java:
--------------------------------------------------------------------------------
1 | package com.abstratt.pluginutils;
2 |
3 | public interface UserFacingException {
4 | public String getUserFacingMessage();
5 | }
6 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.abstratt.eclipsegraphviz
5 | com.abstratt.eclipsegraphviz.parent
6 | 2.13.0
7 | pom
8 |
9 | master
10 | com.abstratt.releng
11 | 4.4.0
12 |
13 |
14 |
15 |
16 |
17 |
18 | github
19 | Abstratt OSS Repo
20 | https://maven.pkg.github.com/abstratt/maven-releases/
21 | default
22 |
23 | true
24 |
25 |
26 |
27 |
28 |
29 |
30 | scm:git:https://github.com/abstratt/eclipsegraphviz.git
31 |
32 |
33 |
34 | plugins/com.abstratt.pluginutils
35 | plugins/com.abstratt.content
36 | plugins/com.abstratt.graphviz
37 | plugins/com.abstratt.graphviz.ui
38 | plugins/com.abstratt.imageviewer
39 | features/com.abstratt.eclipsegraphviz.feature
40 | repositories/com.abstratt.eclipsegraphviz.repository
41 | repositories/com.abstratt.eclipsegraphviz.p2site
42 |
43 |
44 |
45 |
46 |
47 | org.eclipse.tycho
48 | target-platform-configuration
49 | ${tycho-version}
50 |
51 |
52 |
53 | com.abstratt.eclipsegraphviz
54 | com.abstratt.eclipsegraphviz.parent
55 | ${project.version}
56 | dependencies
57 |
58 |
59 | p2
60 |
61 |
62 |
63 | org.eclipse.tycho.extras
64 | target-platform-validation-plugin
65 | ${tycho-version}
66 |
67 |
68 | dependencies.target
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/repositories/com.abstratt.eclipsegraphviz.p2site/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.abstratt.eclipsegraphviz
7 | com.abstratt.eclipsegraphviz.p2site
8 | 2.13.0
9 | pom
10 |
11 | com.abstratt.eclipsegraphviz.parent
12 | com.abstratt.eclipsegraphviz
13 | 2.13.0
14 | ../..
15 |
16 |
17 |
18 |
19 | org.eclipse.tycho
20 | tycho-p2-repository-plugin
21 | ${tycho-version}
22 |
23 |
24 |
25 | true
26 |
27 | package
28 |
29 | assemble-maven-repository
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/repositories/com.abstratt.eclipsegraphviz.repository/category.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/repositories/com.abstratt.eclipsegraphviz.repository/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.abstratt.eclipsegraphviz
7 | com.abstratt.eclipsegraphviz.repository
8 | 2.13.0
9 | eclipse-repository
10 |
11 | com.abstratt.eclipsegraphviz.parent
12 | com.abstratt.eclipsegraphviz
13 | 2.13.0
14 | ../..
15 |
16 |
17 |
--------------------------------------------------------------------------------