001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.studio.apacheds.model;
021
022
023 import java.io.File;
024 import java.io.FileInputStream;
025 import java.io.FileNotFoundException;
026 import java.io.FileOutputStream;
027 import java.io.IOException;
028 import java.io.InputStream;
029 import java.io.OutputStream;
030 import java.util.ArrayList;
031 import java.util.HashMap;
032 import java.util.List;
033 import java.util.Map;
034
035 import org.apache.commons.io.FileUtils;
036 import org.apache.directory.studio.apacheds.ApacheDsPlugin;
037 import org.apache.directory.studio.apacheds.ApacheDsPluginUtils;
038 import org.eclipse.core.runtime.IPath;
039
040
041 /**
042 * This class implements the servers handler.
043 * <p>
044 *
045 * It is used to store all the servers used in the plugin.
046 *
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 * @version $Rev$, $Date$
049 */
050 public class ServersHandler
051 {
052 /** The default instance */
053 private static ServersHandler instance;
054
055 /** The list of servers */
056 private List<Server> serversList;
057
058 /** The map of servers identified by ID */
059 private Map<String, Server> serversIdMap;
060
061 /** The listeners */
062 private List<ServersHandlerListener> listeners;
063
064
065 /**
066 * Creates a new instance of ServersHandler.
067 */
068 private ServersHandler()
069 {
070 // Initializing lists and maps
071 serversList = new ArrayList<Server>();
072 serversIdMap = new HashMap<String, Server>();
073 listeners = new ArrayList<ServersHandlerListener>();
074 }
075
076
077 /**
078 * Gets the default servers handler (singleton pattern).
079 *
080 * @return
081 * the default servers handler
082 */
083 public static ServersHandler getDefault()
084 {
085 if ( instance == null )
086 {
087 instance = new ServersHandler();
088 }
089
090 return instance;
091 }
092
093
094 /**
095 * Adds a server.
096 *
097 * @param server
098 * the server to be added
099 */
100 public void addServer( Server server )
101 {
102 addServer( server, true );
103
104 saveServersToStore();
105 }
106
107
108 /**
109 * Adds a server.
110 *
111 * @param server
112 * the server to be added
113 * @param notifyListeners
114 * <code>true</code> if the listeners need to be notified,
115 * <code>false</code> if not.
116 */
117 private void addServer( Server server, boolean notifyListeners )
118 {
119 if ( !serversList.contains( server ) )
120 {
121 // Adding the server
122 serversList.add( server );
123 serversIdMap.put( server.getId(), server );
124
125 // Notifying listeners
126 if ( notifyListeners )
127 {
128 for ( ServersHandlerListener listener : listeners.toArray( new ServersHandlerListener[0] ) )
129 {
130 listener.serverAdded( server );
131 }
132 }
133 }
134 }
135
136
137 /**
138 * Removes a server.
139 *
140 * @param server
141 * the server to be removed
142 */
143 public void removeServer( Server server )
144 {
145 removeServer( server, true );
146
147 saveServersToStore();
148 }
149
150
151 /**
152 * Removes a server.
153 *
154 * @param server
155 * the server to be removed
156 * @param notifyListeners
157 * <code>true</code> if the listeners need to be notified,
158 * <code>false</code> if not.
159 */
160 private void removeServer( Server server, boolean notifyListeners )
161 {
162 if ( serversList.contains( server ) )
163 {
164 // Removing the server
165 serversList.remove( server );
166 serversIdMap.remove( server.getId() );
167
168 // Notifying listeners
169 if ( notifyListeners )
170 {
171 for ( ServersHandlerListener listener : listeners.toArray( new ServersHandlerListener[0] ) )
172 {
173 listener.serverRemoved( server );
174 }
175 }
176 }
177 }
178
179
180 /**
181 * Indicates if the server handler contains the given server.
182 *
183 * @param server
184 * the server
185 * @return
186 * <code>true</code> if the server hander contains the given server,
187 * <code>false</code> if not
188 */
189 public boolean containsServer( Server server )
190 {
191 return serversList.contains( server );
192 }
193
194
195 /**
196 * Adds a listener to the servers handler.
197 *
198 * @param listener
199 * the listener to add
200 */
201 public void addListener( ServersHandlerListener listener )
202 {
203 if ( !listeners.contains( listener ) )
204 {
205 listeners.add( listener );
206 }
207 }
208
209
210 /**
211 * Removes a listener to the servers handler.
212 *
213 * @param listener
214 * the listener to remove
215 */
216 public void removeListener( ServersHandlerListener listener )
217 {
218 if ( listeners.contains( listener ) )
219 {
220 listeners.remove( listener );
221 }
222 }
223
224
225 /**
226 * Loads the server from the file store.
227 */
228 public void loadServersFromStore()
229 {
230 File store = getServersStorePath().toFile();
231 File tempStore = getServersStoreTempPath().toFile();
232 boolean loadFailed = false;
233 String exceptionMessage = ""; //$NON-NLS-1$
234
235 // We try to load the servers file
236 if ( store.exists() )
237 {
238 try
239 {
240 InputStream inputStream = new FileInputStream( store );
241 List<Server> servers = ServersHandlerIO.read( inputStream );
242 for ( Server server : servers )
243 {
244 addServer( server, false );
245 }
246 return;
247 }
248 catch ( FileNotFoundException e )
249 {
250 loadFailed = true;
251 exceptionMessage = e.getMessage();
252 }
253 catch ( ServersHandlerIOException e )
254 {
255 loadFailed = true;
256 exceptionMessage = e.getMessage();
257 }
258
259 if ( loadFailed )
260 {
261 if ( tempStore.exists() )
262 {
263 // If something went wrong, we try to load the temp servers file
264 try
265 {
266 InputStream inputStream = new FileInputStream( tempStore );
267 List<Server> servers = ServersHandlerIO.read( inputStream );
268 for ( Server server : servers )
269 {
270 addServer( server, false );
271 }
272 return;
273 }
274 catch ( FileNotFoundException e )
275 {
276 ApacheDsPluginUtils.reportError( Messages.getString( "ServersHandler.ErrorLoadingServer" ) //$NON-NLS-1$
277 + e.getMessage() );
278 }
279 catch ( ServersHandlerIOException e )
280 {
281 ApacheDsPluginUtils.reportError( Messages.getString( "ServersHandler.ErrorLoadingServer" ) //$NON-NLS-1$
282 + e.getMessage() );
283 }
284 }
285 else
286 {
287 ApacheDsPluginUtils.reportError( Messages.getString( "ServersHandler.ErrorLoadingServer" ) //$NON-NLS-1$
288 + exceptionMessage );
289 }
290 }
291 }
292 }
293
294
295 /**
296 * Saves the server to the file store.
297 */
298 public void saveServersToStore()
299 {
300 File store = getServersStorePath().toFile();
301 File tempStore = getServersStoreTempPath().toFile();
302 boolean saveFailed = false;
303
304 try
305 {
306 // Saving the servers to the temp servers file
307 OutputStream outputStream = new FileOutputStream( tempStore );
308 ServersHandlerIO.write( serversList, outputStream );
309
310 // Copying the temp servers file to the final location
311 String content = FileUtils.readFileToString( tempStore, "UTF-8" ); //$NON-NLS-1$
312 FileUtils.writeStringToFile( store, content, "UTF-8" ); //$NON-NLS-1$
313 }
314 catch ( FileNotFoundException e )
315 {
316 saveFailed = true;
317 }
318 catch ( IOException e )
319 {
320 saveFailed = true;
321 }
322
323 if ( saveFailed )
324 {
325 // If an error occurs when saving to the temp servers file or
326 // when copying the temp servers file to the final location,
327 // we try to save the servers directly to the final location.
328 try
329 {
330 // Saving the servers to the temp servers file
331 OutputStream outputStream = new FileOutputStream( store );
332 ServersHandlerIO.write( serversList, outputStream );
333 outputStream.close();
334 }
335 catch ( FileNotFoundException e )
336 {
337 ApacheDsPluginUtils
338 .reportError( Messages.getString( "ServersHandler.ErrorLoadingServer" ) + e.getMessage() ); //$NON-NLS-1$
339 }
340 catch ( IOException e )
341 {
342 ApacheDsPluginUtils
343 .reportError( Messages.getString( "ServersHandler.ErrorLoadingServer" ) + e.getMessage() ); //$NON-NLS-1$
344 }
345 }
346 }
347
348
349 /**
350 * Gets the path to the server file.
351 *
352 * @return
353 * the path to the server file.
354 */
355 private IPath getServersStorePath()
356 {
357 return ApacheDsPlugin.getDefault().getStateLocation().append( "servers.xml" ); //$NON-NLS-1$
358 }
359
360
361 /**
362 * Gets the path to the server temp file.
363 *
364 * @return
365 * the path to the server temp file.
366 */
367 private IPath getServersStoreTempPath()
368 {
369 return ApacheDsPlugin.getDefault().getStateLocation().append( "servers-temp.xml" ); //$NON-NLS-1$
370 }
371
372
373 /**
374 * Indicates if the given is available (i.e. not already taken by another
375 * server).
376 *
377 * @param name
378 * the name
379 * @return
380 * <code>true</code> if the name is available, <code>false</code> if
381 * not
382 */
383 public boolean isNameAvailable( String name )
384 {
385 for ( Server server : serversList )
386 {
387 if ( server.getName().equalsIgnoreCase( name ) )
388 {
389 return false;
390 }
391 }
392
393 return true;
394 }
395
396
397 /**
398 * Gets the servers list.
399 *
400 * @return
401 * the servers list.
402 */
403 public List<Server> getServersList()
404 {
405 return serversList;
406 }
407
408
409 /**
410 * Gets the server associated with the given id.
411 *
412 * @return
413 * the server associated witht the given id.
414 */
415 public Server getServerById( String id )
416 {
417 return serversIdMap.get( id );
418 }
419 }