EMMA Coverage Report (generated Thu Nov 26 15:54:18 CST 2009)
[all classes][org.eclipse.pde.api.tools.internal]

COVERAGE SUMMARY FOR SOURCE FILE [ApiDescriptionManager.java]

nameclass, %method, %block, %line, %
ApiDescriptionManager.java100% (1/1)81%  (17/21)54%  (478/883)62%  (146.6/238)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ApiDescriptionManager100% (1/1)81%  (17/21)54%  (478/883)62%  (146.6/238)
abort (String, Throwable): void 0%   (0/1)0%   (0/13)0%   (0/2)
getInt (Element, String): int 0%   (0/1)0%   (0/10)0%   (0/4)
restoreNode (ProjectApiDescription, Element, ApiDescription$ManifestNode, Map... 0%   (0/1)0%   (0/282)0%   (0/61)
rollback (ISaveContext): void 0%   (0/1)0%   (0/1)0%   (0/1)
restoreChildren (ProjectApiDescription, Element, ApiDescription$ManifestNode,... 100% (1/1)41%  (11/27)48%  (2.9/6)
restoreDescription (IJavaProject, ProjectApiDescription): boolean 100% (1/1)67%  (78/116)68%  (17.7/26)
getApiDescription (PluginProjectApiComponent, BundleDescription): IApiDescrip... 100% (1/1)71%  (34/48)67%  (8/12)
getLong (Element, String): long 100% (1/1)75%  (9/12)60%  (3/5)
saving (ISaveContext): void 100% (1/1)79%  (45/57)85%  (11/13)
flushElementCache (IJavaElementDelta): void 100% (1/1)88%  (44/50)90%  (19/21)
clean (IJavaProject, boolean, boolean): void 100% (1/1)89%  (47/53)93%  (14/15)
processJavaElementDeltas (IJavaElementDelta [], IJavaProject): void 100% (1/1)97%  (143/147)98%  (43/44)
<static initializer> 100% (1/1)100% (4/4)100% (3/3)
ApiDescriptionManager (): void 100% (1/1)100% (14/14)100% (5/5)
doneSaving (ISaveContext): void 100% (1/1)100% (1/1)100% (1/1)
elementChanged (ElementChangedEvent): void 100% (1/1)100% (9/9)100% (3/3)
getDefault (): ApiDescriptionManager 100% (1/1)100% (8/8)100% (3/3)
prepareToSave (ISaveContext): void 100% (1/1)100% (1/1)100% (1/1)
projectChanged (IJavaProject): void 100% (1/1)100% (11/11)100% (4/4)
projectClasspathChanged (IJavaProject): void 100% (1/1)100% (11/11)100% (4/4)
shutdown (): void 100% (1/1)100% (8/8)100% (4/4)

1/*******************************************************************************
2 * Copyright (c) 2008, 2009 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 *******************************************************************************/
11package org.eclipse.pde.api.tools.internal;
12 
13import java.io.BufferedInputStream;
14import java.io.File;
15import java.io.FileInputStream;
16import java.io.IOException;
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.List;
21import java.util.Map;
22import java.util.Map.Entry;
23import java.util.jar.JarFile;
24 
25import org.eclipse.core.resources.ISaveContext;
26import org.eclipse.core.resources.ISaveParticipant;
27import org.eclipse.core.runtime.CoreException;
28import org.eclipse.core.runtime.IPath;
29import org.eclipse.core.runtime.IStatus;
30import org.eclipse.core.runtime.Status;
31import org.eclipse.jdt.core.ElementChangedEvent;
32import org.eclipse.jdt.core.ICompilationUnit;
33import org.eclipse.jdt.core.IElementChangedListener;
34import org.eclipse.jdt.core.IJavaElement;
35import org.eclipse.jdt.core.IJavaElementDelta;
36import org.eclipse.jdt.core.IJavaProject;
37import org.eclipse.jdt.core.IPackageFragment;
38import org.eclipse.jdt.core.IType;
39import org.eclipse.jdt.core.JavaCore;
40import org.eclipse.osgi.service.resolver.BundleDescription;
41import org.eclipse.pde.api.tools.internal.ApiDescription.ManifestNode;
42import org.eclipse.pde.api.tools.internal.ProjectApiDescription.TypeNode;
43import org.eclipse.pde.api.tools.internal.model.ApiModelCache;
44import org.eclipse.pde.api.tools.internal.model.PluginProjectApiComponent;
45import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
46import org.eclipse.pde.api.tools.internal.provisional.Factory;
47import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
48import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
49import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor;
50import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
51import org.eclipse.pde.api.tools.internal.provisional.scanner.ScannerMessages;
52import org.eclipse.pde.api.tools.internal.util.Util;
53import org.w3c.dom.Element;
54import org.w3c.dom.Node;
55import org.w3c.dom.NodeList;
56 
57import com.ibm.icu.text.MessageFormat;
58 
59/**
60 * Manages a cache of API descriptions for Java projects. Descriptions
61 * are re-used between API components for the same project.
62 * 
63 * @since 1.0
64 */
65public final class ApiDescriptionManager implements IElementChangedListener, ISaveParticipant {
66        
67        /**
68         * Singleton
69         */
70        private static ApiDescriptionManager fgDefault;
71        
72        /**
73         * Maps Java projects to API descriptions
74         */
75        private Map fDescriptions = new HashMap();
76        
77        /**
78         * Path to the local directory where API descriptions are cached
79         * per project.
80         */
81        public static final IPath API_DESCRIPTIONS_CONTAINER_PATH =
82                ApiPlugin.getDefault().getStateLocation();
83 
84        /**
85         * Constructs an API description manager.
86         */
87        private ApiDescriptionManager() {
88                JavaCore.addElementChangedListener(this, ElementChangedEvent.POST_CHANGE);
89                ApiPlugin.getDefault().addSaveParticipant(this);
90        }
91 
92        /**
93         * Cleans up Java element listener
94         */
95        public static void shutdown() {
96                if (fgDefault != null) {
97                        JavaCore.removeElementChangedListener(fgDefault);
98                        ApiPlugin.getDefault().removeSaveParticipant(fgDefault);
99                }
100        }
101        
102        /**
103         * Returns the singleton API description manager.
104         * 
105         * @return API description manager
106         */
107        public synchronized static ApiDescriptionManager getDefault() {
108                if (fgDefault == null) {
109                        fgDefault = new ApiDescriptionManager();
110                }
111                return fgDefault;
112        }
113        
114        /**
115         * Returns an API description for the given project component and connect it to the
116         * given bundle description.
117         * 
118         * @param project Java project
119         * @return API description
120         */
121        public synchronized IApiDescription getApiDescription(PluginProjectApiComponent component, BundleDescription bundle) {
122                IJavaProject project = component.getJavaProject();
123                ProjectApiDescription description = (ProjectApiDescription) fDescriptions.get(project);
124                if (description == null) {
125                        if (Util.isApiProject(project)) {
126                                description = new ProjectApiDescription(project);
127                        } else {
128                                description = new NonApiProjectDescription(project);
129                        }
130                        try {
131                                restoreDescription(project, description);
132                        } catch (CoreException e) {
133                                ApiPlugin.log(e.getStatus());
134                                description = new ProjectApiDescription(project);
135                        }
136                        fDescriptions.put(project, description);
137                }
138                return description;
139        }
140        /**
141         * Cleans the API description for the given project.
142         * 
143         * @param project
144         * @param delete whether to delete the file on disk
145         * @param remove whether to remove the cached API description
146         */
147        public synchronized void clean(IJavaProject project, boolean delete, boolean remove) {
148                ProjectApiDescription desc = null;
149                if (remove) {
150                        desc = (ProjectApiDescription) fDescriptions.remove(project);
151                } else {
152                        desc = (ProjectApiDescription) fDescriptions.get(project);
153                }
154                if (desc != null) {
155                        desc.clean();
156                }
157                if (delete) {
158                        File file = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName())
159                                .append(IApiCoreConstants.API_DESCRIPTION_XML_NAME).toFile();
160                        if (file.exists()) {
161                                file.delete();
162                        }
163                        file = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName()).toFile();
164                        if(file.exists() && file.isDirectory()) {
165                                file.delete();
166                        }
167                }
168        }
169        
170        /**
171         * Notifies the API description that the underlying project has changed.
172         * 
173         * @param project
174         */
175        synchronized void projectChanged(IJavaProject project) {
176                ProjectApiDescription desc = (ProjectApiDescription) fDescriptions.get(project);
177                if (desc != null) {
178                        desc.projectChanged();
179                }
180        }
181 
182        /**
183         * Notifies the API description that the underlying project classpath has changed.
184         * 
185         * @param project
186         */
187        synchronized void projectClasspathChanged(IJavaProject project) {
188                ProjectApiDescription desc = (ProjectApiDescription) fDescriptions.get(project);
189                if (desc != null) {
190                        desc.projectClasspathChanged();
191                }
192        }
193 
194        /* (non-Javadoc)
195         * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
196         */
197        public void elementChanged(ElementChangedEvent event) {
198                IJavaElementDelta delta = event.getDelta();
199                processJavaElementDeltas(delta.getAffectedChildren(), null);
200        }
201        
202        /**
203         * Remove projects that get closed or removed.
204         * 
205         * @param deltas
206         */
207        private synchronized void processJavaElementDeltas(IJavaElementDelta[] deltas, IJavaProject proj) {
208                IJavaElementDelta delta = null;
209                for(int i = 0; i < deltas.length; i++) {
210                        delta = deltas[i];
211                        switch(delta.getElement().getElementType()) {
212                                case IJavaElement.JAVA_PROJECT: {
213                                        IJavaProject jproj = (IJavaProject) delta.getElement();
214                                        switch (delta.getKind()) {
215                                                case IJavaElementDelta.CHANGED:
216                                                        int flags = delta.getFlags();
217                                                        if((flags & IJavaElementDelta.F_CLOSED) != 0) {
218                                                                clean(jproj, false, true);
219                                                                flushElementCache(delta);
220                                                        } else if((flags & (IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED
221                                                                        | IJavaElementDelta.F_CLASSPATH_CHANGED)) != 0) {
222                                                                if (jproj != null) {
223                                                                        projectClasspathChanged(jproj);
224                                                                        flushElementCache(delta);
225                                                                }
226                                                        } else if((flags & IJavaElementDelta.F_CONTENT) != 0) {
227                                                                if (jproj != null) {
228                                                                        processJavaElementDeltas(delta.getAffectedChildren(), jproj);
229                                                                }
230                                                        } else if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
231                                                                processJavaElementDeltas(delta.getAffectedChildren(), jproj);
232                                                        }
233                                                        break;
234                                                case IJavaElementDelta.REMOVED:
235                                                        clean(jproj, true, true);
236                                                        flushElementCache(delta);
237                                                        break;
238                                        }
239                                        break;
240                                }
241                                case IJavaElement.PACKAGE_FRAGMENT : {
242                                        int flags = delta.getFlags();
243                                        if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
244                                                processJavaElementDeltas(delta.getAffectedChildren(), proj);
245                                        }
246                                        break;
247                                }
248                                case IJavaElement.PACKAGE_FRAGMENT_ROOT : {
249                                        int flags = delta.getFlags();
250                                        if ((flags & (IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED
251                                                        | IJavaElementDelta.F_ADDED_TO_CLASSPATH
252                                                        | IJavaElementDelta.F_REMOVED_FROM_CLASSPATH)) != 0) {
253                                                projectClasspathChanged(proj);
254                                        } else if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
255                                                processJavaElementDeltas(delta.getAffectedChildren(), proj);
256                                        }
257                                        break;
258                                }
259                                case IJavaElement.COMPILATION_UNIT : {
260                                        int flags = delta.getFlags();
261                                        switch (delta.getKind()) {
262                                                case IJavaElementDelta.CHANGED: {
263                                                        if ((flags & (IJavaElementDelta.F_CONTENT | 
264                                                                                        IJavaElementDelta.F_FINE_GRAINED | 
265                                                                                        IJavaElementDelta.F_PRIMARY_RESOURCE)) != 0){
266                                                                if (proj != null) {
267                                                                        projectChanged(proj);
268                                                                        flushElementCache(delta);
269                                                                        continue;
270                                                                }
271                                                        }
272                                                        break;
273                                                }
274                                                case IJavaElementDelta.ADDED :
275                                                case IJavaElementDelta.REMOVED : {
276                                                        if (proj != null) {
277                                                                projectChanged(proj);
278                                                                flushElementCache(delta);
279                                                                continue;
280                                                        }
281                                                }
282                                        }
283                                }
284                        }
285                }
286        }
287 
288        /**
289         * Flushes the changed element from the model cache
290         * @param delta
291         */
292        void flushElementCache(IJavaElementDelta delta) {
293                IJavaElement element = delta.getElement();
294                if((delta.getFlags() & IJavaElementDelta.F_MOVED_TO) > 0) {
295                        element = delta.getMovedToElement();
296                }
297                if((delta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0) {
298                        element = delta.getMovedFromElement();
299                }
300                switch(element.getElementType()) {
301                        case IJavaElement.COMPILATION_UNIT: {
302                                ICompilationUnit unit = (ICompilationUnit) element;
303                                IType type = unit.findPrimaryType();
304                                if(type != null) {
305                                        ApiModelCache.getCache().removeElementInfo(
306                                                        ApiBaselineManager.WORKSPACE_API_BASELINE_ID,
307                                                        element.getJavaProject().getElementName(), 
308                                                        type.getFullyQualifiedName(), 
309                                                        IApiElement.TYPE);
310                                }
311                                break;
312                        }
313                        case IJavaElement.JAVA_PROJECT: {
314                                ApiModelCache.getCache().removeElementInfo(
315                                                ApiBaselineManager.WORKSPACE_API_BASELINE_ID,
316                                                element.getElementName(), 
317                                                null, 
318                                                IApiElement.COMPONENT);
319                                break;
320                        }
321                }
322        }
323        
324        /* (non-Javadoc)
325         * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
326         */
327        public void doneSaving(ISaveContext context) {
328        }
329 
330        /* (non-Javadoc)
331         * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
332         */
333        public void prepareToSave(ISaveContext context) throws CoreException {
334        }
335 
336        /* (non-Javadoc)
337         * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
338         */
339        public void rollback(ISaveContext context) {
340        }
341 
342        /* (non-Javadoc)
343         * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
344         */
345        public synchronized void saving(ISaveContext context) throws CoreException {
346                Iterator entries = fDescriptions.entrySet().iterator();
347                while (entries.hasNext()) {
348                        Entry entry = (Entry) entries.next();
349                        IJavaProject project = (IJavaProject) entry.getKey();
350                        ProjectApiDescription desc = (ProjectApiDescription) entry.getValue();
351                        if (desc.isModified()) {
352                                File dir = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName()).toFile();
353                                dir.mkdirs();
354                                String xml = desc.getXML();
355                                try {
356                                        Util.saveFile(new File(dir,  IApiCoreConstants.API_DESCRIPTION_XML_NAME), xml);
357                                } catch (IOException e) {
358                                        abort(MessageFormat.format(ScannerMessages.ApiDescriptionManager_0, new String[]{project.getElementName()}), e);
359                                }
360                        }
361                }
362        }        
363        
364        /**
365         * Restores the API description from its saved file, if any and returns
366         * true if successful.
367         * 
368         * @param project
369         * @param description
370         * @return whether the restore succeeded
371         * @throws CoreException 
372         */
373        private boolean restoreDescription(IJavaProject project, ProjectApiDescription description) throws CoreException {
374                File file = API_DESCRIPTIONS_CONTAINER_PATH.append(project.getElementName()).
375                        append(IApiCoreConstants.API_DESCRIPTION_XML_NAME).toFile();
376                if (file.exists()) {
377                        BufferedInputStream stream = null;
378                        try {
379                                stream = new BufferedInputStream(new FileInputStream(file));
380                                String xml = new String(Util.getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8));
381                                Element root = Util.parseDocument(xml);
382                                if (!root.getNodeName().equals(IApiXmlConstants.ELEMENT_COMPONENT)) {
383                                        abort(ScannerMessages.ComponentXMLScanner_0, null); 
384                                }
385                                long timestamp = getLong(root, IApiXmlConstants.ATTR_MODIFICATION_STAMP);
386                                String version = root.getAttribute(IApiXmlConstants.ATTR_VERSION);
387                                description.setEmbeddedVersion(version);
388                                if (IApiXmlConstants.API_DESCRIPTION_CURRENT_VERSION.equals(version)) {
389                                        description.fPackageTimeStamp = timestamp;
390                                        description.fManifestFile = project.getProject().getFile(JarFile.MANIFEST_NAME);
391                                        restoreChildren(description, root, null, description.fPackageMap);
392                                        return true;
393                                }
394                        } catch (IOException e) {
395                                abort(MessageFormat.format(ScannerMessages.ApiDescriptionManager_1,
396                                                new String[]{project.getElementName()}), e);
397                        } finally {
398                                if (stream != null) {
399                                        try {
400                                                stream.close();
401                                        } catch (IOException e) {
402                                                // ignore
403                                        }
404                                }
405                        }
406                }
407                return false;
408        }
409        
410        private void restoreChildren(ProjectApiDescription apiDesc, Element element, ManifestNode parentNode, Map childrenMap) throws CoreException {
411                NodeList children = element.getChildNodes();
412                for (int i = 0; i < children.getLength(); i++) {
413                        Node child = children.item(i);
414                        if (child.getNodeType() == Node.ELEMENT_NODE) {
415                                restoreNode(apiDesc, (Element) child, parentNode, childrenMap);
416                        }
417                }
418        }
419        
420        private void restoreNode(ProjectApiDescription apiDesc, Element element, ManifestNode parentNode, Map childrenMap) throws CoreException {
421                ManifestNode node = null;
422                IElementDescriptor elementDesc = null;
423                if (element.getTagName().equals(IApiXmlConstants.ELEMENT_PACKAGE)) {
424                        int vis = getInt(element, IApiXmlConstants.ATTR_VISIBILITY);
425                        int res = getInt(element, IApiXmlConstants.ATTR_RESTRICTIONS);
426                        // collect fragments
427                        List fragments = new ArrayList();
428                        NodeList childNodes = element.getChildNodes();
429                        String pkgName = null;
430                        for (int i = 0; i < childNodes.getLength(); i++) {
431                                Node child = childNodes.item(i);
432                                if (child.getNodeType() == Node.ELEMENT_NODE) {
433                                        if (((Element)child).getTagName().equals(IApiXmlConstants.ELEMENT_PACKAGE_FRAGMENT)) {
434                                                Element fragment = (Element) child;
435                                                String handle = fragment.getAttribute(IApiXmlConstants.ATTR_HANDLE);
436                                                IJavaElement je = JavaCore.create(handle);
437                                                if (je.getElementType() != IJavaElement.PACKAGE_FRAGMENT) {
438                                                        abort(ScannerMessages.ApiDescriptionManager_2 + handle, null);
439                                                }
440                                                pkgName = je.getElementName();
441                                                fragments.add(je);
442                                        }
443                                }
444                        }
445                        if (!fragments.isEmpty()) {
446                                elementDesc = Factory.packageDescriptor(pkgName);
447                                node = apiDesc.newPackageNode((IPackageFragment[])fragments.toArray(new IPackageFragment[fragments.size()]), parentNode, elementDesc, vis, res);
448                        } else {
449                                abort(ScannerMessages.ApiDescriptionManager_2, null);
450                        }
451                } else if (element.getTagName().equals(IApiXmlConstants.ELEMENT_PACKAGE_FRAGMENT)) {
452                        return; // nothing to do
453                } else if (element.getTagName().equals(IApiXmlConstants.ELEMENT_TYPE)) {
454                        String handle = element.getAttribute(IApiXmlConstants.ATTR_HANDLE);
455                        int vis = getInt(element, IApiXmlConstants.ATTR_VISIBILITY);
456                        int res = getInt(element, IApiXmlConstants.ATTR_RESTRICTIONS);
457                        IJavaElement je = JavaCore.create(handle);
458                        if (je.getElementType() != IJavaElement.TYPE) {
459                                abort(ScannerMessages.ApiDescriptionManager_3 + handle, null);
460                        }
461                        IType type = (IType) je;
462                        elementDesc = Factory.typeDescriptor(type.getFullyQualifiedName('$'));
463                        TypeNode tn = apiDesc.newTypeNode(type, parentNode, elementDesc, vis, res);
464                        node = tn;
465                        tn.fTimeStamp = getLong(element, IApiXmlConstants.ATTR_MODIFICATION_STAMP);
466                } else if (element.getTagName().equals(IApiXmlConstants.ELEMENT_FIELD)) {
467                        if(parentNode.element instanceof IReferenceTypeDescriptor) {
468                                IReferenceTypeDescriptor type = (IReferenceTypeDescriptor) parentNode.element;
469                                int vis = getInt(element, IApiXmlConstants.ATTR_VISIBILITY);
470                                int res = getInt(element, IApiXmlConstants.ATTR_RESTRICTIONS);
471                                String name = element.getAttribute(IApiXmlConstants.ATTR_NAME);
472                                elementDesc = type.getField(name);
473                                node = apiDesc.newNode(parentNode, elementDesc, vis, res);
474                        }
475                } else if (element.getTagName().equals(IApiXmlConstants.ELEMENT_METHOD)) {
476                        if(parentNode.element instanceof IReferenceTypeDescriptor) {
477                                IReferenceTypeDescriptor type = (IReferenceTypeDescriptor) parentNode.element;
478                                int vis = getInt(element, IApiXmlConstants.ATTR_VISIBILITY);
479                                int res = getInt(element, IApiXmlConstants.ATTR_RESTRICTIONS);
480                                String name = element.getAttribute(IApiXmlConstants.ATTR_NAME);
481                                String sig = element.getAttribute(IApiXmlConstants.ATTR_SIGNATURE);
482                                if (sig.indexOf('.') != -1) {
483                                        // old files might use '.' instead of '/'
484                                        sig = sig.replace('.', '/');
485                                }
486                                elementDesc = type.getMethod(name,sig);
487                                node = apiDesc.newNode(parentNode, elementDesc, vis, res);
488                        }
489                }
490                if (node == null) {
491                        abort(ScannerMessages.ApiDescriptionManager_4, null);
492                }
493                childrenMap.put(elementDesc, node);
494                restoreChildren(apiDesc, element, node, node.children);
495        }
496        
497        /**
498         * Returns an integer attribute.
499         * 
500         * @param element element with the integer
501         * @param attr attribute name
502         * @return attribute value as an integer
503         */
504        private int getInt(Element element, String attr) {
505                String attribute = element.getAttribute(attr);
506                try {
507                        return Integer.parseInt(attribute);
508                } 
509                catch (NumberFormatException e) {}
510                return 0;
511        }
512        
513        /**
514         * Returns a long attribute.
515         * 
516         * @param element element with the long
517         * @param attr attribute name
518         * @return attribute value as an long
519         */
520        private long getLong(Element element, String attr) {
521                String attribute = element.getAttribute(attr);
522                if (attribute != null) {
523                        try {
524                                return Long.parseLong(attribute);
525                        } 
526                        catch (NumberFormatException e) {}
527                }
528                return 0L;
529        }        
530        
531        /**
532         * Throws an exception with the given message and underlying exception.
533         * 
534         * @param message error message
535         * @param exception underlying exception, or <code>null</code>
536         * @throws CoreException
537         */
538        private static void abort(String message, Throwable exception) throws CoreException {
539                IStatus status = new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, message, exception);
540                throw new CoreException(status);
541        }
542}

[all classes][org.eclipse.pde.api.tools.internal]
EMMA 2.0.5312 EclEmma Fix 1 (C) Vladimir Roubtsov