Avoid NPE for "Mark Occurrences"
[phpeclipse.git] / net.sourceforge.phpeclipse.webbrowser / src / net / sourceforge / phpeclipse / webbrowser / internal / BrowserManager.java
1 /**********************************************************************
2  * Copyright (c) 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7   *
8  * Contributors:
9  *    IBM - Initial API and implementation
10  **********************************************************************/
11 package net.sourceforge.phpeclipse.webbrowser.internal;
12
13 import java.io.ByteArrayInputStream;
14 import java.io.InputStreamReader;
15 import java.io.Reader;
16 import java.io.StringWriter;
17 import java.util.ArrayList;
18 import java.util.Iterator;
19 import java.util.List;
20
21 import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowser;
22 import net.sourceforge.phpeclipse.webbrowser.IExternalWebBrowserWorkingCopy;
23 import net.sourceforge.phpeclipse.webbrowser.IInternalWebBrowser;
24 import net.sourceforge.phpeclipse.webbrowser.IWebBrowser;
25
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Preferences;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.ui.IMemento;
30 import org.eclipse.ui.XMLMemento;
31
32 /**
33  *  
34  */
35 public class BrowserManager {
36   private static final int ADD = 0;
37
38   private static final int CHANGE = 1;
39
40   private static final int REMOVE = 2;
41
42   protected List browsers;
43
44   protected IWebBrowser currentBrowser;
45
46   protected List browserListeners = new ArrayList();
47
48   private Preferences.IPropertyChangeListener pcl;
49
50   protected boolean ignorePreferenceChanges = false;
51
52   protected static BrowserManager instance;
53
54   public static BrowserManager getInstance() {
55     if (instance == null)
56       instance = new BrowserManager();
57     return instance;
58   }
59
60   private BrowserManager() {
61     pcl = new Preferences.IPropertyChangeListener() {
62       public void propertyChange(Preferences.PropertyChangeEvent event) {
63         if (ignorePreferenceChanges)
64           return;
65         String property = event.getProperty();
66         if (property.equals("browsers")) {
67           loadBrowsers();
68         }
69       }
70     };
71
72     WebBrowserUIPlugin.getInstance().getPluginPreferences().addPropertyChangeListener(pcl);
73   }
74
75   protected void dispose() {
76     WebBrowserUIPlugin.getInstance().getPluginPreferences().removePropertyChangeListener(pcl);
77
78     // clear the cache
79     if (browsers != null) {
80       Iterator iterator = browsers.iterator();
81       while (iterator.hasNext()) {
82         Object obj = iterator.next();
83         if (obj instanceof IInternalWebBrowser) {
84           IInternalWebBrowser wb = (IInternalWebBrowser) obj;
85           if (wb.getClearHistoryOnExit())
86             WebBrowserPreference.setInternalWebBrowserHistory(null);
87         }
88       }
89     }
90   }
91
92   public IExternalWebBrowserWorkingCopy createExternalWebBrowser() {
93     return new ExternalWebBrowserWorkingCopy();
94   }
95
96   public List getWebBrowsers() {
97     if (browsers == null)
98       loadBrowsers();
99     return new ArrayList(browsers);
100   }
101
102   protected void loadBrowsers() {
103     Trace.trace(Trace.FINEST, "Loading web browsers");
104
105     Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
106     String xmlString = prefs.getString("browsers");
107     if (xmlString != null && xmlString.length() > 0) {
108       browsers = new ArrayList();
109
110       try {
111         ByteArrayInputStream in = new ByteArrayInputStream(xmlString.getBytes());
112         Reader reader = new InputStreamReader(in);
113         IMemento memento = XMLMemento.createReadRoot(reader);
114
115         IMemento child = memento.getChild("internal");
116         if (child != null) {
117           InternalWebBrowser browser = new InternalWebBrowser();
118           browser.load(child);
119           browsers.add(browser);
120         }
121
122         IMemento[] children = memento.getChildren("external");
123         int size = children.length;
124         for (int i = 0; i < size; i++) {
125           ExternalWebBrowser browser = new ExternalWebBrowser();
126           browser.load(children[i]);
127           browsers.add(browser);
128         }
129
130         Integer current = memento.getInteger("current");
131         if (current != null) {
132           currentBrowser = (IWebBrowser) browsers.get(current.intValue());
133         }
134       } catch (Exception e) {
135         Trace.trace(Trace.WARNING, "Could not load browsers: " + e.getMessage());
136       }
137       addInternalBrowser(browsers);
138       if (currentBrowser == null && browsers.size() > 0)
139         currentBrowser = (IWebBrowser) browsers.get(0);
140     } else {
141       setupDefaultBrowsers();
142       saveBrowsers();
143       return;
144     }
145   }
146
147   protected void saveBrowsers() {
148     try {
149       ignorePreferenceChanges = true;
150       XMLMemento memento = XMLMemento.createWriteRoot("web-browsers");
151
152       Iterator iterator = browsers.iterator();
153       while (iterator.hasNext()) {
154         Object obj = iterator.next();
155         if (obj instanceof InternalWebBrowser) {
156           InternalWebBrowser browser = (InternalWebBrowser) obj;
157           IMemento child = memento.createChild("internal");
158           browser.save(child);
159         } else if (obj instanceof ExternalWebBrowser) {
160           ExternalWebBrowser browser = (ExternalWebBrowser) obj;
161           IMemento child = memento.createChild("external");
162           browser.save(child);
163         }
164       }
165
166       memento.putInteger("current", browsers.indexOf(currentBrowser));
167
168       StringWriter writer = new StringWriter();
169       memento.save(writer);
170       String xmlString = writer.getBuffer().toString();
171       Preferences prefs = WebBrowserUIPlugin.getInstance().getPluginPreferences();
172       prefs.setValue("browsers", xmlString);
173       WebBrowserUIPlugin.getInstance().savePluginPreferences();
174     } catch (Exception e) {
175       Trace.trace(Trace.SEVERE, "Could not save browsers", e);
176     }
177     ignorePreferenceChanges = false;
178   }
179
180   protected void addInternalBrowser(List browserList) {
181     if (browserList == null)
182       return;
183
184     Iterator iterator = browserList.iterator();
185     while (iterator.hasNext()) {
186       IWebBrowser browser = (IWebBrowser) iterator.next();
187       if (browser instanceof IInternalWebBrowser)
188         return;
189     }
190
191     // add the internal browser if we can
192 //    WebBrowserUIPlugin.getInstance().getLog().log(
193 //        new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0, WebBrowserUtil.canUseInternalWebBrowser() + "/"
194 //            + WebBrowserUtil.isInternalBrowserOperational(), null));
195 //    if (!WebBrowserUtil.canUseInternalWebBrowser() || !WebBrowserUtil.isInternalBrowserOperational())
196 //      return;
197     WebBrowserUIPlugin.getInstance().getLog().log(
198         new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0, 
199             "-"+WebBrowserUtil.isInternalBrowserOperational(), null));
200     if (!WebBrowserUtil.isInternalBrowserOperational())
201       return;
202     browserList.add(0, new InternalWebBrowser());
203   }
204
205   private void setupDefaultBrowsers() {
206     browsers = new ArrayList();
207
208     addInternalBrowser(browsers);
209
210     // handle all the EXTERNAL browsers by criteria and add those too at startup
211     WebBrowserUtil.addFoundBrowsers(browsers);
212
213     // by default, if internal is there, that is current, else set the first external one
214     if (!browsers.isEmpty())
215       currentBrowser = (IWebBrowser) browsers.get(0);
216   }
217
218   protected void addBrowser(IExternalWebBrowser browser) {
219     if (browsers == null)
220       loadBrowsers();
221     if (!browsers.contains(browser))
222       browsers.add(browser);
223     fireWebBrowserEvent(browser, ADD);
224     saveBrowsers();
225   }
226
227   protected void removeWebBrowser(IExternalWebBrowser browser) {
228     if (browsers == null)
229       loadBrowsers();
230     browsers.remove(browser);
231     fireWebBrowserEvent(browser, REMOVE);
232   }
233
234   // Internal Web browser CAN be "edited", just not created or removed
235   protected void browserChanged(IWebBrowser browser) {
236     fireWebBrowserEvent(browser, CHANGE);
237     saveBrowsers();
238   }
239
240   /**
241    * Add Web browser listener.
242    * 
243    * @param listener
244    */
245   public void addWebBrowserListener(IWebBrowserListener listener) {
246     browserListeners.add(listener);
247   }
248
249   /**
250    * Remove Web browser listener.
251    * 
252    * @param listener
253    */
254   public void removeWebBrowserListener(IWebBrowserListener listener) {
255     browserListeners.remove(listener);
256   }
257
258   /**
259    * Fire a Web browser event.
260    * 
261    * @param browser
262    * @param type
263    */
264   protected void fireWebBrowserEvent(IWebBrowser browser, int type) {
265     Object[] obj = browserListeners.toArray();
266
267     int size = obj.length;
268     for (int i = 0; i < size; i++) {
269       IWebBrowserListener listener = (IWebBrowserListener) obj[i];
270       if (type == ADD)
271         listener.browserAdded(browser);
272       else if (type == CHANGE)
273         listener.browserChanged(browser);
274       else if (type == REMOVE)
275         listener.browserRemoved(browser);
276     }
277   }
278
279   public IWebBrowser getCurrentWebBrowser() {
280     if (browsers == null)
281       loadBrowsers();
282
283     return currentBrowser;
284   }
285
286   public void setCurrentWebBrowser(IWebBrowser wb) {
287     if (browsers.contains(wb))
288       currentBrowser = wb;
289     saveBrowsers();
290   }
291 }