001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.ide;
011:
012: import java.io.IOException;
013: import java.io.InputStream;
014: import java.net.URL;
015: import java.util.zip.CRC32;
016: import java.util.zip.CheckedInputStream;
017:
018: import org.eclipse.core.runtime.Assert;
019: import org.eclipse.core.runtime.IBundleGroup;
020: import org.eclipse.core.runtime.IBundleGroupProvider;
021: import org.eclipse.core.runtime.IProduct;
022: import org.eclipse.core.runtime.Path;
023: import org.eclipse.core.runtime.Platform;
024: import org.eclipse.jface.resource.ImageDescriptor;
025: import org.eclipse.ui.internal.BundleGroupProperties;
026: import org.eclipse.ui.internal.ProductProperties;
027:
028: /**
029: * The information within this object is obtained from the about INI file.
030: * This file resides within an install configurations directory and must be a
031: * standard java property file.
032: * <p>
033: * This class is not intended to be instantiated or subclassed by clients.
034: * </p>
035: */
036: public final class AboutInfo {
037: private ProductProperties productProperties;
038:
039: private BundleGroupProperties bundleGroupProperties;
040:
041: private Long featureImageCRC;
042:
043: private boolean calculatedImageCRC = false;
044:
045: /**
046: * The information contained in this info will apply to only the argument product.
047: */
048: public AboutInfo(IProduct product) {
049: this .productProperties = new ProductProperties(product);
050: }
051:
052: /**
053: * This info object will apply to the argument bundle group.
054: */
055: public AboutInfo(IBundleGroup bundleGroup) {
056: this .bundleGroupProperties = new BundleGroupProperties(
057: bundleGroup);
058: }
059:
060: /**
061: * Returns the configuration information for the feature with the given id.
062: *
063: * @param featureId
064: * the feature id
065: * @param versionId
066: * the version id (of the feature)
067: * @return the configuration information for the feature
068: */
069: public static AboutInfo readFeatureInfo(String featureId,
070: String versionId) {
071: Assert.isNotNull(featureId);
072: Assert.isNotNull(versionId);
073:
074: // first see if the id matches the product
075: IProduct product = Platform.getProduct();
076: if (product != null
077: && featureId.equals(ProductProperties
078: .getProductId(product))) {
079: return new AboutInfo(product);
080: }
081:
082: // then check the bundle groups
083: IBundleGroup bundleGroup = getBundleGroup(featureId, versionId);
084: if (bundleGroup != null) {
085: return new AboutInfo(bundleGroup);
086: }
087:
088: return null;
089: }
090:
091: private static IBundleGroup getBundleGroup(String id,
092: String versionId) {
093: if (id == null || versionId == null) {
094: return null;
095: }
096:
097: IBundleGroupProvider[] providers = Platform
098: .getBundleGroupProviders();
099: for (int p = 0; p < providers.length; ++p) {
100: IBundleGroup[] groups = providers[p].getBundleGroups();
101: for (int g = 0; g < groups.length; ++g) {
102: if (id.equals(groups[g].getIdentifier())
103: && versionId.equals(groups[g].getVersion())) {
104: return groups[g];
105: }
106: }
107: }
108:
109: return null;
110: }
111:
112: /**
113: * Returns the descriptor for an image which can be shown in an "about" dialog
114: * for this product. Products designed to run "headless" typically would not
115: * have such an image.
116: *
117: * @return the descriptor for an about image, or <code>null</code> if none
118: */
119: public ImageDescriptor getAboutImage() {
120: return productProperties == null ? null : productProperties
121: .getAboutImage();
122: }
123:
124: /**
125: * Returns the descriptor for an image which can be shown in an "about features"
126: * dialog. Products designed to run "headless" typically would not have such an image.
127: *
128: * @return the descriptor for a feature image, or <code>null</code> if none
129: */
130: public ImageDescriptor getFeatureImage() {
131: return bundleGroupProperties == null ? null
132: : bundleGroupProperties.getFeatureImage();
133: }
134:
135: /**
136: * Returns the simple name of the feature image file.
137: *
138: * @return the simple name of the feature image file,
139: * or <code>null</code> if none
140: */
141: public String getFeatureImageName() {
142: if (bundleGroupProperties == null) {
143: return null;
144: }
145:
146: URL url = bundleGroupProperties.getFeatureImageUrl();
147: return url == null ? null : new Path(url.getPath())
148: .lastSegment();
149: }
150:
151: /**
152: * Returns the CRC of the feature image as supplied in the properties file.
153: *
154: * @return the CRC of the feature image, or <code>null</code> if none
155: */
156: public Long getFeatureImageCRC() {
157: if (bundleGroupProperties == null) {
158: return null;
159: }
160:
161: if (!calculatedImageCRC) {
162: featureImageCRC = calculateImageCRC(bundleGroupProperties
163: .getFeatureImageUrl());
164: calculatedImageCRC = featureImageCRC != null;
165: }
166:
167: return featureImageCRC;
168: }
169:
170: /**
171: * Calculate a CRC for the feature image
172: */
173: private static Long calculateImageCRC(URL url) {
174: if (url == null) {
175: return null;
176: }
177:
178: InputStream in = null;
179: try {
180: CRC32 checksum = new CRC32();
181: in = new CheckedInputStream(url.openStream(), checksum);
182:
183: // the contents don't matter, the read just needs a place to go
184: byte[] sink = new byte[2048];
185: while (true) {
186: if (in.read(sink) <= 0) {
187: break;
188: }
189: }
190:
191: return new Long(checksum.getValue());
192: } catch (IOException e) {
193: return null;
194: } finally {
195: if (in != null) {
196: try {
197: in.close();
198: } catch (IOException e) {
199: // do nothing
200: }
201: }
202: }
203: }
204:
205: /**
206: * Returns a label for the feature plugn, or <code>null</code>.
207: */
208: public String getFeatureLabel() {
209: if (productProperties != null) {
210: return productProperties.getProductName();
211: }
212: if (bundleGroupProperties != null) {
213: return bundleGroupProperties.getFeatureLabel();
214: }
215: return null;
216: }
217:
218: /**
219: * Returns the id for this feature.
220: *
221: * @return the feature id
222: */
223: public String getFeatureId() {
224: String id = null;
225: if (productProperties != null) {
226: id = productProperties.getProductId();
227: } else if (bundleGroupProperties != null) {
228: id = bundleGroupProperties.getFeatureId();
229: }
230: return id != null ? id : ""; //$NON-NLS-1$
231: }
232:
233: /**
234: * Returns the text to show in an "about" dialog for this product.
235: * Products designed to run "headless" typically would not have such text.
236: *
237: * @return the about text, or <code>null</code> if none
238: */
239: public String getAboutText() {
240: return productProperties == null ? null : productProperties
241: .getAboutText();
242: }
243:
244: /**
245: * Returns the application name or <code>null</code>.
246: * Note this is never shown to the user.
247: * It is used to initialize the SWT Display.
248: * <p>
249: * On Motif, for example, this can be used
250: * to set the name used for resource lookup.
251: * </p>
252: *
253: * @return the application name, or <code>null</code>
254: *
255: * @see org.eclipse.swt.widgets.Display#setAppName
256: */
257: public String getAppName() {
258: return productProperties == null ? null : productProperties
259: .getAppName();
260: }
261:
262: /**
263: * Returns the product name or <code>null</code>.
264: * This is shown in the window title and the About action.
265: *
266: * @return the product name, or <code>null</code>
267: */
268: public String getProductName() {
269: return productProperties == null ? null : productProperties
270: .getProductName();
271: }
272:
273: /**
274: * Returns the provider name or <code>null</code>.
275: *
276: * @return the provider name, or <code>null</code>
277: */
278: public String getProviderName() {
279: return bundleGroupProperties == null ? null
280: : bundleGroupProperties.getProviderName();
281: }
282:
283: /**
284: * Returns the feature version id.
285: *
286: * @return the version id of the feature
287: */
288: public String getVersionId() {
289: return bundleGroupProperties == null ? "" : bundleGroupProperties.getFeatureVersion(); //$NON-NLS-1$
290: }
291:
292: /**
293: * Returns a <code>URL</code> for the welcome page.
294: * Products designed to run "headless" typically would not have such an page.
295: *
296: * @return the welcome page, or <code>null</code> if none
297: */
298: public URL getWelcomePageURL() {
299: if (productProperties != null) {
300: return productProperties.getWelcomePageUrl();
301: }
302: if (bundleGroupProperties != null) {
303: return bundleGroupProperties.getWelcomePageUrl();
304: }
305: return null;
306: }
307:
308: /**
309: * Returns the ID of a perspective in which to show the welcome page.
310: * May be <code>null</code>.
311: *
312: * @return the welcome page perspective id, or <code>null</code> if none
313: */
314: public String getWelcomePerspectiveId() {
315: return bundleGroupProperties == null ? null
316: : bundleGroupProperties.getWelcomePerspective();
317: }
318:
319: /**
320: * Returns a <code>String</code> for the tips and trick href.
321: *
322: * @return the tips and tricks href, or <code>null</code> if none
323: */
324: public String getTipsAndTricksHref() {
325: return bundleGroupProperties == null ? null
326: : bundleGroupProperties.getTipsAndTricksHref();
327: }
328:
329: /**
330: * Return an array of image descriptors for the window images to use for
331: * this product. The expectations is that the elements will be the same
332: * image rendered at different sizes. Products designed to run "headless"
333: * typically would not have such images.
334: *
335: * @return an array of the image descriptors for the window images, or
336: * <code>null</code> if none
337: * @since 3.0
338: */
339: public ImageDescriptor[] getWindowImages() {
340: return productProperties == null ? null : productProperties
341: .getWindowImages();
342: }
343: }
|