Workaround for feature request #1154254 (sticky browser URL) that solves bug #1827766...
[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()
73                                 .addPropertyChangeListener(pcl);
74         }
75
76         protected void dispose() {
77                 WebBrowserUIPlugin.getInstance().getPluginPreferences()
78                                 .removePropertyChangeListener(pcl);
79
80                 // clear the cache
81                 if (browsers != null) {
82                         Iterator iterator = browsers.iterator();
83                         while (iterator.hasNext()) {
84                                 Object obj = iterator.next();
85                                 if (obj instanceof IInternalWebBrowser) {
86                                         IInternalWebBrowser wb = (IInternalWebBrowser) obj;
87                                         if (wb.getClearHistoryOnExit())
88                                                 WebBrowserPreference.setInternalWebBrowserHistory(null);
89                                 }
90                         }
91                 }
92         }
93
94         public IExternalWebBrowserWorkingCopy createExternalWebBrowser() {
95                 return new ExternalWebBrowserWorkingCopy();
96         }
97
98         public List getWebBrowsers() {
99                 if (browsers == null)
100                         loadBrowsers();
101                 return new ArrayList(browsers);
102         }
103
104         protected void loadBrowsers() {
105                 Trace.trace(Trace.FINEST, "Loading web browsers");
106
107                 Preferences prefs = WebBrowserUIPlugin.getInstance()
108                                 .getPluginPreferences();
109                 String xmlString = prefs.getString("browsers");
110                 if (xmlString != null && xmlString.length() > 0) {
111                         browsers = new ArrayList();
112
113                         try {
114                                 ByteArrayInputStream in = new ByteArrayInputStream(xmlString
115                                                 .getBytes());
116                                 Reader reader = new InputStreamReader(in);
117                                 IMemento memento = XMLMemento.createReadRoot(reader);
118
119                                 IMemento child = memento.getChild("internal");
120                                 if (child != null) {
121                                         InternalWebBrowser browser = new InternalWebBrowser();
122                                         browser.load(child);
123                                         browsers.add(browser);
124                                 }
125
126                                 IMemento[] children = memento.getChildren("external");
127                                 int size = children.length;
128                                 for (int i = 0; i < size; i++) {
129                                         ExternalWebBrowser browser = new ExternalWebBrowser();
130                                         browser.load(children[i]);
131                                         browsers.add(browser);
132                                 }
133
134                                 Integer current = memento.getInteger("current");
135                                 if (current != null) {
136                                         currentBrowser = (IWebBrowser) browsers.get(current
137                                                         .intValue());
138                                 }
139                         } catch (Exception e) {
140                                 Trace.trace(Trace.WARNING, "Could not load browsers: "
141                                                 + e.getMessage());
142                         }
143                         addInternalBrowser(browsers);
144                         if (currentBrowser == null && browsers.size() > 0)
145                                 currentBrowser = (IWebBrowser) browsers.get(0);
146                 } else {
147                         setupDefaultBrowsers();
148                         saveBrowsers();
149                         return;
150                 }
151         }
152
153         protected void saveBrowsers() {
154                 try {
155                         ignorePreferenceChanges = true;
156                         XMLMemento memento = XMLMemento.createWriteRoot("web-browsers");
157
158                         Iterator iterator = browsers.iterator();
159                         while (iterator.hasNext()) {
160                                 Object obj = iterator.next();
161                                 if (obj instanceof InternalWebBrowser) {
162                                         InternalWebBrowser browser = (InternalWebBrowser) obj;
163                                         IMemento child = memento.createChild("internal");
164                                         browser.save(child);
165                                 } else if (obj instanceof ExternalWebBrowser) {
166                                         ExternalWebBrowser browser = (ExternalWebBrowser) obj;
167                                         IMemento child = memento.createChild("external");
168                                         browser.save(child);
169                                 }
170                         }
171
172                         memento.putInteger("current", browsers.indexOf(currentBrowser));
173
174                         StringWriter writer = new StringWriter();
175                         memento.save(writer);
176                         String xmlString = writer.getBuffer().toString();
177                         Preferences prefs = WebBrowserUIPlugin.getInstance()
178                                         .getPluginPreferences();
179                         prefs.setValue("browsers", xmlString);
180                         WebBrowserUIPlugin.getInstance().savePluginPreferences();
181                 } catch (Exception e) {
182                         Trace.trace(Trace.SEVERE, "Could not save browsers", e);
183                 }
184                 ignorePreferenceChanges = false;
185         }
186
187         protected void addInternalBrowser(List browserList) {
188                 if (browserList == null)
189                         return;
190
191                 Iterator iterator = browserList.iterator();
192                 while (iterator.hasNext()) {
193                         IWebBrowser browser = (IWebBrowser) iterator.next();
194                         if (browser instanceof IInternalWebBrowser)
195                                 return;
196                 }
197
198                 // add the internal browser if we can
199                 // WebBrowserUIPlugin.getInstance().getLog().log(
200                 // new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0,
201                 // WebBrowserUtil.canUseInternalWebBrowser() + "/"
202                 // + WebBrowserUtil.isInternalBrowserOperational(), null));
203                 // if (!WebBrowserUtil.canUseInternalWebBrowser() ||
204                 // !WebBrowserUtil.isInternalBrowserOperational())
205                 // return;
206                 WebBrowserUIPlugin.getInstance().getLog().log(
207                                 new Status(IStatus.INFO, WebBrowserUIPlugin.PLUGIN_ID, 0, "-"
208                                                 + WebBrowserUtil.isInternalBrowserOperational(), null));
209                 if (!WebBrowserUtil.isInternalBrowserOperational())
210                         return;
211                 browserList.add(0, new InternalWebBrowser());
212         }
213
214         private void setupDefaultBrowsers() {
215                 browsers = new ArrayList();
216
217                 addInternalBrowser(browsers);
218
219                 // handle all the EXTERNAL browsers by criteria and add those too at
220                 // startup
221                 WebBrowserUtil.addFoundBrowsers(browsers);
222
223                 // by default, if internal is there, that is current, else set the first
224                 // external one
225                 if (!browsers.isEmpty())
226                         currentBrowser = (IWebBrowser) browsers.get(0);
227         }
228
229         protected void addBrowser(IExternalWebBrowser browser) {
230                 if (browsers == null)
231                         loadBrowsers();
232                 if (!browsers.contains(browser))
233                         browsers.add(browser);
234                 fireWebBrowserEvent(browser, ADD);
235                 saveBrowsers();
236         }
237
238         protected void removeWebBrowser(IExternalWebBrowser browser) {
239                 if (browsers == null)
240                         loadBrowsers();
241                 browsers.remove(browser);
242                 fireWebBrowserEvent(browser, REMOVE);
243         }
244
245         // Internal Web browser CAN be "edited", just not created or removed
246         protected void browserChanged(IWebBrowser browser) {
247                 fireWebBrowserEvent(browser, CHANGE);
248                 saveBrowsers();
249         }
250
251         /**
252          * Add Web browser listener.
253          * 
254          * @param listener
255          */
256         public void addWebBrowserListener(IWebBrowserListener listener) {
257                 browserListeners.add(listener);
258         }
259
260         /**
261          * Remove Web browser listener.
262          * 
263          * @param listener
264          */
265         public void removeWebBrowserListener(IWebBrowserListener listener) {
266                 browserListeners.remove(listener);
267         }
268
269         /**
270          * Fire a Web browser event.
271          * 
272          * @param browser
273          * @param type
274          */
275         protected void fireWebBrowserEvent(IWebBrowser browser, int type) {
276                 Object[] obj = browserListeners.toArray();
277
278                 int size = obj.length;
279                 for (int i = 0; i < size; i++) {
280                         IWebBrowserListener listener = (IWebBrowserListener) obj[i];
281                         if (type == ADD)
282                                 listener.browserAdded(browser);
283                         else if (type == CHANGE)
284                                 listener.browserChanged(browser);
285                         else if (type == REMOVE)
286                                 listener.browserRemoved(browser);
287                 }
288         }
289
290         public IWebBrowser getCurrentWebBrowser() {
291                 if (browsers == null)
292                         loadBrowsers();
293
294                 return currentBrowser;
295         }
296
297         public void setCurrentWebBrowser(IWebBrowser wb) {
298                 if (browsers.contains(wb))
299                         currentBrowser = wb;
300                 saveBrowsers();
301         }
302 }