Source code: javax/ide/build/BuildSystem.java
1 package javax.ide.build;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6
7 import java.util.ListIterator;
8 import javax.ide.Service;
9 import javax.ide.spi.ProviderNotFoundException;
10 import javax.ide.build.spi.BuildSystemHook;
11 import javax.ide.command.Context;
12 import javax.ide.extension.ExtensionRegistry;
13
14 /**
15 * The <code>BuildSystem</code> service allows extension writers to
16 * initiate a build and query information from the build system.
17 */
18 public abstract class BuildSystem extends Service
19 {
20
21 /*
22 * A list of build listener instances.
23 */
24 private final List _listeners = new ArrayList();
25
26
27 protected BuildSystem()
28 {
29
30 }
31
32 /**
33 * Initializes the build system manager.
34 * <p>
35 * This implementation retrieves and registers listeners obtained from
36 * the build system hook handler.
37 */
38 protected void initialize()
39 {
40 BuildSystemHook hook = (BuildSystemHook)
41 ExtensionRegistry.getExtensionRegistry().getHook( BuildSystemHook.ELEMENT );
42 _listeners.addAll( hook.getListeners() );
43 }
44
45 /**
46 * Add an {@link javax.ide.build.BuildListener}.
47 *
48 * @param l the {@link javax.ide.build.BuildListener} to add.
49 */
50 public final void addBuildListener( BuildListener l )
51 {
52 _listeners.add( l );
53 }
54
55 /**
56 * Remove an {@link javax.ide.build.BuildListener}.
57 *
58 * @param l The {@link javax.ide.build.BuildListener} to remove.
59 */
60 public final void removeBuildListener( BuildListener l )
61 {
62 _listeners.remove( l );
63 }
64
65 /**
66 * Start a build of the objects selected in the {@link Context}. This
67 * method starts the build in another thread and returns immediately.
68 *
69 * @param context the objects returned by calling the
70 * {@link Context#getSelection} method are build using the classpath
71 * and source path information provided by the context project.
72 */
73 public abstract void build( Context context );
74
75 /**
76 * Check if the build system is currently building something.
77 *
78 * @return <code>true</code> is a build is in progress.
79 */
80 public abstract boolean isBuilding();
81
82 /**
83 * Notifies listeners that the compiler is about to start building. This
84 * method fires the {@link BuildListener#preBuild} method. If any
85 * of the registered listeners <code>preBuild</code> method throws
86 * an exception during its execution, the {@link BuildListener#postBuild}
87 * method is called on all listeners whose <code>preBuild</code> method
88 * succeeded. This gives those listeners a chance to clean up.
89 *
90 * @param event the event object to fire to listeners.
91 * @throws AbortBuildException thrown when a listener's
92 * <code>preBuild</code> method call throws an exception. The
93 * {@link java.lang.Exception#getCause()} method can be used to retrieve
94 * the exception thrown by the listener.
95 */
96 protected final void firePreBuild( BuildEvent event )
97 throws AbortBuildException
98 {
99 // Clone the listener list for safety.
100 final List listeners = new ArrayList( _listeners.size() );
101 listeners.addAll( _listeners );
102
103 for ( ListIterator i = listeners.listIterator(); i.hasNext(); )
104 {
105 BuildListener listener = (BuildListener) i.next();
106
107 try
108 {
109 listener.preBuild( event );
110 }
111 catch ( Exception e )
112 {
113 BuildEvent failedEvent = new BuildEvent( event.getBuildSystem(),
114 event.getContext(), false );
115 while ( i.hasPrevious() )
116 {
117 listener = (BuildListener) i.previous();
118 listener.postBuild( failedEvent );
119 }
120 throw new AbortBuildException( e.getMessage(), e );
121 }
122 }
123 }
124
125 /**
126 * Notifies listeners that the compiler has finished compiling documents.
127 *
128 * @param event
129 */
130 protected final void firePostBuild( BuildEvent event )
131 {
132 // Clone the listener list for safety.
133 final List listeners = new ArrayList( _listeners.size() );
134 listeners.addAll( _listeners );
135
136 for ( Iterator i = listeners.iterator(); i.hasNext(); )
137 {
138 final BuildListener listener = (BuildListener) i.next();
139
140 try
141 {
142 listener.postBuild( event );
143 }
144 catch ( Exception e )
145 {
146 // Convert the event into a build failed event.
147 event = new BuildEvent(event.getBuildSystem(),
148 event.getContext(), false );
149 }
150 }
151 }
152
153 /**
154 * Gets the build system implementation.
155 *
156 * @return the build system implementation for this IDE.
157 */
158 public static BuildSystem getBuildSystem()
159 {
160 try
161 {
162 return (BuildSystem) getService( BuildSystem.class );
163 }
164 catch ( ProviderNotFoundException nse )
165 {
166 nse.printStackTrace();
167 throw new IllegalStateException( "No build system service." );
168 }
169 }
170 }