Skip to main content
summaryrefslogtreecommitdiffstats
blob: 2a88ad6c09d4ffedef65f73f5e4575f39043ad19 (plain) (blame)
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
/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Cameron Bateman/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.core.runtime.IAdaptable;

/**
 * An abstract implementation of the IDelegatingFactory interface
 * 
 * Clients may extend this class.
 * 
 * @author cbateman
 * 
 */
public abstract class AbstractDelegatingFactory implements IDelegatingFactory
{

    /* instance attributes */

    /**
     * the list of registered factory delegates
     */
    protected final CopyOnWriteArrayList<IAdaptable> _delegates;

    private final List<Class> _supportedDelegates;

    /**
     * @param supportedDelegateTypes
     *            -- populates the list of classes used by the isValidDelegate
     *            contract
     */
    protected AbstractDelegatingFactory(final Class[] supportedDelegateTypes)
    {
        _delegates = new CopyOnWriteArrayList<IAdaptable>();

        final List<Class> supportedTypes = new ArrayList<Class>();
        supportedTypes.addAll(Arrays.asList(supportedDelegateTypes));
        _supportedDelegates = Collections.unmodifiableList(supportedTypes);
    }

    /**
     * @see org.eclipse.jst.jsf.context.IDelegatingFactory#addFactoryDelegate(org.eclipse.core.runtime.IAdaptable)
     */
    public final void addFactoryDelegate(final IAdaptable delegate)
    {
        if (isValidDelegate(delegate))
        {
        	synchronized(_delegates)
        	{
        		_delegates.addIfAbsent(delegate);
        		if (_delegates.size() > 1)
        		{
        			List<IAdaptable> delegates = new ArrayList<IAdaptable>(_delegates);

        			Collections.sort(delegates, new Comparator()
        			{
						public int compare(Object delegate1, Object delegate2) 
						{
							final Class<?>  clazz1 = delegate1.getClass();
							final Class<?>  clazz2 = delegate2.getClass();
							
							Package package1 = clazz1.getPackage();
							Package package2 = clazz2.getPackage();
							boolean package1IsOSS = package1.getName().startsWith("org.eclipse.jst"); //$NON-NLS-1$
							boolean package2IsOSS = package2.getName().startsWith("org.eclipse.jst"); //$NON-NLS-1$
							
							if (package1IsOSS && !package2IsOSS)
							{
								// sort the oss one after the non-oss one
								return 1;
							}
							else if (!package1IsOSS && package2IsOSS)
							{
								return -1;
							}
							
							// otherwise they are either both oss or both non-oss, so just
							// sort canonically by name.
							return clazz1.getName().compareTo(clazz2.getName());
						}
        			});
        			_delegates.clear();
        			_delegates.addAll(delegates);
        		}
        	}
        }
    }

    /**
     * @see org.eclipse.jst.jsf.context.IDelegatingFactory#removeFactoryDelegate(org.eclipse.core.runtime.IAdaptable)
     */
    public final boolean removeFactoryDelegate(final IAdaptable delegate)
    {
        return _delegates.remove(delegate);
    }

    /**
     * @see org.eclipse.jst.jsf.context.IDelegatingFactory#getValidDelegateTypes()
     */
    public final List<Class> getValidDelegateTypes()
    {
        return _supportedDelegates;
    }

    /**
     * @see org.eclipse.jst.jsf.context.IDelegatingFactory#isValidDelegate(org.eclipse.core.runtime.IAdaptable)
     */
    public final boolean isValidDelegate(final IAdaptable delegate)
    {
        for (final Class clazz : _supportedDelegates)
        {
            // if the delegate supports one of the valid delegate classes
            // via adaptation, then it is a valid delegate
            if (delegate.getAdapter(clazz) != null)
            {
                return true;
            }
        }

        // if no found, delegate is not supported
        return false;
    }
}

Back to the top