Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: cf241f6e0b1bb1b07314fad03f8b7c8e202f6577 (plain) (tree)
1
2
3
4
5
6
7
8
9
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
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478





























































































































































































































































































































































































































































































                                                                                                                                                                               
/*****************************************************************************
 * Copyright (c) 2008 CEA LIST.
 *
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
 *  Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Added support for Image's name
 *
 *****************************************************************************/

package org.eclipse.papyrus.uml.tools.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.Image;
import org.eclipse.uml2.uml.Stereotype;

// TODO: Auto-generated Javadoc
/**
 * Utility class for <code>org.eclipse.uml2.uml.Image</code><BR>
 */
public class ImageUtil {

	/**
	 * ID of the EAnnotation where "expression" (used to select stereotype icon) is stored on image.
	 */
	public static final String IMAGE_PAPYRUS_EA = "image_papyrus";

	/**
	 * KEY of the EAnnotation where "expression" (used to select stereotype icon) is stored on
	 * image.
	 */
	public static final String IMAGE_EXPR_KEY = "image_expr_key";

	/**
	 * KEY of the EAnnotation where "kind" (kind = icon/shape) is stored on image.
	 */
	public static final String IMAGE_KIND_KEY = "image_kind_key";

	/**
	 * KEY of the EAnnotation where the image's name is stored
	 *
	 * @see {@link #getName(Image)}
	 * @see {@link #setName(Image, String)}
	 */
	public static final String IMAGE_NAME_KEY = "image_name_key";

	/**
	 * Set the content of an {@link Image} with a file (containing an image).
	 *
	 * @param image
	 *            the UML {@link Image} to set
	 * @param imageFile
	 *            the icon
	 */
	// @unused
	public static void setContent(Image image, File imageFile) {

		try {
			String rawImageData = "";
			if (imageFile != null) {
				byte[] byteFlow = getBytesFromFile(imageFile);

				rawImageData = "";

				// file reading
				for (byte element : byteFlow) {
					rawImageData = rawImageData + element + "%";
				}
			} else {
				rawImageData = null;
			}

			image.setContent(rawImageData);

		} catch (Exception ex) {
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getLocalizedMessage(), ex));
		}
	}

	/**
	 * Get the content of an {@link Image} as {@link org.eclipse.swt.graphics.Image}
	 *
	 * @param image
	 *            the UML {@link Image} to set
	 *
	 * @return {@link org.eclipse.swt.graphics.Image} content
	 */
	public static org.eclipse.swt.graphics.Image getContent(Image image) throws Exception {

		if (image == null) {
			// null parameter
			return null;
		}

		if (image.getContent() == null) {
			// null image
			return null;
		}

		// else
		String rawData = image.getContent();
		StringTokenizer strToken = new StringTokenizer(rawData, "%");
		byte[] target = new byte[strToken.countTokens()];

		// decoding image
		int j = 0;
		while (strToken.hasMoreTokens()) {
			target[j] = (new Byte(strToken.nextToken()).byteValue());
			j++;
		}

		org.eclipse.swt.graphics.Image decodedImage = new org.eclipse.swt.graphics.Image(null, new ByteArrayInputStream(target));

		return decodedImage;
	}

	/**
	 * Get the image specified by the location property of an {@link Image} as {@link org.eclipse.swt.graphics.Image}
	 *
	 * @param image
	 *            the UML {@link Image} to set
	 *
	 * @return {@link org.eclipse.swt.graphics.Image} image
	 */
	public static org.eclipse.swt.graphics.Image getImageFromLocation(Image image) {

		org.eclipse.swt.graphics.Image swtImage = null;

		// Try to instantiate an SWT image from the path stored
		// in UML Image location property
		String location = image.getLocation();
		if ((location != null) && !("".equals(location))) {

			URI iconURI = URI.createURI(location);
			if (iconURI.isRelative()) {
				String err_msg = "Incorrect implementation of relative location." + location;
				Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, err_msg, new Exception(err_msg)));
				URI pluginURI = URI.createPlatformPluginURI(location, true); // <- TODO : fix this to retrieve the related plug-in URI
				iconURI = iconURI.resolve(pluginURI);
			}

			try {
				ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(new URL(iconURI.toString()));
				swtImage = imageDescriptor.createImage();

			} catch (Exception e) {
				Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Could not create image from location : " + location, e));
			}
		}

		return swtImage;
	}

	/**
	 * Read an image file content.
	 *
	 * @param file
	 *            the file
	 *
	 * @return a table of bytes of the file content
	 *
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public static byte[] getBytesFromFile(File file) throws IOException {

		InputStream is = new FileInputStream(file);

		// Get the size of the file
		long length = file.length();

		// You cannot create an array using a long type.
		// It needs to be an int type.
		// Before converting to an int type, check
		// to ensure that file is not larger than Integer.MAX_VALUE.
		if (length > Integer.MAX_VALUE) {
			is.close();
			throw new IOException("Image too big to encode");
		}

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) length];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while ((offset < bytes.length) && ((numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			is.close();
			throw new IOException("Could not completely read file " + file.getName());
		}

		// Close the input stream and return bytes
		is.close();

		return bytes;
	}

	/**
	 * Associates an expression to an image.
	 *
	 * @param image
	 *            the image
	 * @param expression
	 *            the expression
	 */
	public static void setExpression(Image image, String expression) {

		EAnnotation ea_Image = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		// Create annotation for icon selection if it does not exist
		if (ea_Image == null) {
			ea_Image = image.createEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		}

		// If expression == "" remove the EAnnotation
		if ("".equals(expression)) {
			ea_Image.getDetails().removeKey(IMAGE_EXPR_KEY);
		} else {
			ea_Image.getDetails().put(ImageUtil.IMAGE_EXPR_KEY, expression);
		}

		cleanImageAnnotation(ea_Image);
	}

	/**
	 * Returns the expression associated to the image.
	 *
	 * @param image
	 *            the image
	 *
	 * @return the expression associated to the image
	 */
	public static String getExpression(org.eclipse.uml2.uml.Image image) {
		EAnnotation ea_ImageExpr = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);

		String expr = null;
		if ((ea_ImageExpr != null) && (ea_ImageExpr.getDetails().containsKey(ImageUtil.IMAGE_EXPR_KEY))) {
			expr = ea_ImageExpr.getDetails().get(ImageUtil.IMAGE_EXPR_KEY);
		}
		return expr;
	}

	/**
	 * Associates a name to an Image.
	 *
	 * The UML Image is not a NamedElement : the name is stored as an
	 * EAnnotation, and is not mandatory. The name should only be used for
	 * displaying the image's label : this is *not* an identifier.
	 *
	 * @param image
	 *            The image
	 * @param name
	 *            The name
	 */
	public static void setName(Image image, String name) {
		EAnnotation ea_Image = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		// Create annotation for icon selection if it does not exist
		if (ea_Image == null) {
			ea_Image = image.createEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		}

		// If expression == "" remove the EAnnotation
		if ("".equals(name)) {
			ea_Image.getDetails().removeKey(IMAGE_NAME_KEY);
		} else {
			ea_Image.getDetails().put(ImageUtil.IMAGE_NAME_KEY, name);
		}

		cleanImageAnnotation(ea_Image);
	}

	/**
	 * Returns the name associated to the image
	 *
	 * The UML Image is not a NamedElement : the name is stored as an
	 * EAnnotation, and is not mandatory. The name should only be used for
	 * displaying the image's label : this is *not* an identifier.
	 *
	 * @param image
	 *            the image
	 * @return
	 * 		the name associated to the image
	 */
	public static String getName(Image image) {
		EAnnotation ea_Image = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);

		String name = null;
		if ((ea_Image != null) && (ea_Image.getDetails().containsKey(IMAGE_NAME_KEY))) {
			name = ea_Image.getDetails().get(IMAGE_NAME_KEY);
		}
		return name;
	}

	/**
	 * Removes the EAnnotation from the Image if the annotation doesn't contain any valid key
	 *
	 * @param annotation
	 */
	private static void cleanImageAnnotation(EAnnotation annotation) {
		EMap<String, String> details = annotation.getDetails();
		if (details.isEmpty()) {
			// if(!(details.containsKey(IMAGE_NAME_KEY)) && !(details.containsKey(IMAGE_KIND_KEY) && !(details.containsKey(IMAGE_NAME_KEY)))) {
			annotation.setEModelElement(null);
		}

	}

	/**
	 * Associates kind to an image.
	 *
	 * @param image
	 *            the image
	 * @param kind
	 *            of image (icon / shape)
	 */
	// @unused
	public static void setKind(org.eclipse.uml2.uml.Image image, String kind) {

		EAnnotation ea_Image = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		// Create annotation for icon selection if it does not exist
		if (ea_Image == null) {
			ea_Image = image.createEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);
		}

		// If expression == "" remove the EAnnotation
		if ("".equals(kind)) {
			ea_Image.getDetails().removeKey(IMAGE_KIND_KEY);
		} else {
			ea_Image.getDetails().put(ImageUtil.IMAGE_KIND_KEY, kind);
		}

		cleanImageAnnotation(ea_Image);
	}

	/**
	 * Returns the kind of the image (icon or shape for Papyrus).
	 *
	 * @param image
	 *            the image
	 *
	 * @return kind of image
	 */
	public static String getKind(org.eclipse.uml2.uml.Image image) {
		EAnnotation ea_ImageExpr = image.getEAnnotation(ImageUtil.IMAGE_PAPYRUS_EA);

		String kind = null;
		if ((ea_ImageExpr != null) && (ea_ImageExpr.getDetails().containsKey(ImageUtil.IMAGE_KIND_KEY))) {
			kind = ea_ImageExpr.getDetails().get(ImageUtil.IMAGE_KIND_KEY);
		}
		return kind;
	}

	/**
	 * Evaluates the "Expression" EAnnotation associated to the image.
	 *
	 * @param element
	 *            on which the stereotype (owning current image) is applied
	 * @param image
	 *            the image
	 *
	 * @return true if the expression is correct
	 */
	public static boolean evalExpression(Image image, Element element) {
		/*
		 * Expression has the form : propName = Literal
		 */

		/* Firstly we extract the propertyName and the literal */

		String propName = null;
		String literal = null;
		Stereotype st = (Stereotype) image.getOwner();

		// Retrieve Expression
		String expression = ImageUtil.getExpression(image);
		if (expression == null) {
			// No expression to check
			return false;
		}

		// Parse and test expression
		StringTokenizer sToken = new StringTokenizer(expression.replace(" ", ""), "=");
		if (sToken.countTokens() == 2) {
			propName = sToken.nextToken();
			literal = sToken.nextToken();

		} else {
			// Bad formed expression --> ignore
			return false;
		}

		if (element.getValue(st, propName) != null) {
			/* extract property value from applied stereotype */
			Object val = element.getValue(st, propName);

			if (val instanceof EnumerationLiteral) {
				if (((EnumerationLiteral) val).getLabel().equals(literal)) {
					return true;
				}
			} else if (val instanceof Enumerator) {
				if (((Enumerator) val).getName().equals(literal)) {
					return true;
				}
			}
		}
		// In any other case (bad expression, not property found...)
		return false;
	}

	/**
	 * Test expression on every image, stop on first verified expression.
	 *
	 * @param element
	 *            the element to check
	 * @param images
	 *            the list of images to check
	 *
	 * @return first image verifying its expression
	 */
	public static Image findImageVerifyingExpression(Element element, EList<Image> images) {

		Image image = null;
		Iterator<Image> it = images.iterator();
		while ((image == null) && it.hasNext()) {
			Image current = it.next();
			if (ImageUtil.evalExpression(current, element)) {
				image = current;
			}
		}

		return image;
	}

	/**
	 * Create an Id to store and retrieve image (SWT) In registry.
	 *
	 * @param image
	 *            the image
	 *
	 * @return the image id
	 */
	public static String getImageId(Image image) {
		String id = "";

		Stereotype owner = (Stereotype) image.getOwner();
		id += owner.getQualifiedName() + "_img_" + owner.getIcons().indexOf(image);

		return id;

	}
}

Back to the top