~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to logger/uihandlerserver/src/java/org/netbeans/server/uihandler/TipOfTheDay.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
package org.netbeans.server.uihandler;
 
42
 
 
43
import org.netbeans.server.uihandler.statistics.*;
 
44
import org.netbeans.server.uihandler.*;
 
45
import java.io.IOException;
 
46
import java.io.InputStream;
 
47
import java.net.MalformedURLException;
 
48
import java.net.URL;
 
49
import java.util.ArrayList;
 
50
import java.util.Collections;
 
51
import java.util.HashMap;
 
52
import java.util.LinkedList;
 
53
import java.util.List;
 
54
import java.util.Map;
 
55
import java.util.Queue;
 
56
import java.util.Random;
 
57
import java.util.Set;
 
58
import java.util.logging.Level;
 
59
import java.util.logging.Logger;
 
60
import javax.xml.parsers.ParserConfigurationException;
 
61
import javax.xml.parsers.SAXParser;
 
62
import javax.xml.parsers.SAXParserFactory;
 
63
import org.openide.util.Exceptions;
 
64
import org.openide.util.RequestProcessor;
 
65
import org.xml.sax.Attributes;
 
66
import org.xml.sax.SAXException;
 
67
import org.xml.sax.helpers.DefaultHandler;
 
68
 
 
69
/** Class that provides access to tip of the day functionality provided
 
70
 * by docs team. It is created with URL refering to the page with XML data
 
71
 * and is refereshed very hour.
 
72
 *
 
73
 * @author Jaroslav Tulach
 
74
 */
 
75
public final class TipOfTheDay implements Runnable {
 
76
    private static final Logger LOG = Logger.getLogger(TipOfTheDay.class.getName());
 
77
    private static RequestProcessor RP = new RequestProcessor("Refresh TipOfTheDay");
 
78
    
 
79
    private Map<String,List<Tip>> tips;
 
80
    private final URL url;
 
81
    private RequestProcessor.Task refresh;
 
82
    
 
83
    private TipOfTheDay(URL url) {
 
84
        this.url = url;
 
85
        if (url == null) {
 
86
            tips = Collections.emptyMap();
 
87
            return;
 
88
        }
 
89
        tips = Collections.emptyMap();
 
90
 
 
91
        refresh = RP.create(this);
 
92
        refresh.schedule(0);
 
93
        
 
94
        try {
 
95
            refresh.waitFinished(10000);
 
96
        } catch (InterruptedException ex) {
 
97
            LOG.log(Level.WARNING, ex.getMessage(), ex);
 
98
        }
 
99
    }
 
100
    
 
101
    /** Parses content provided by some URL and create the TipOfTheDay database.
 
102
     * @param url url to read the TipOfTheDay from
 
103
     */
 
104
    public static TipOfTheDay create(URL url) {
 
105
        return new TipOfTheDay(url);
 
106
    }
 
107
    
 
108
    private static TipOfTheDay DEFAULT;
 
109
    /** Gets default tip of the day.
 
110
     */
 
111
    public static TipOfTheDay getDefault() {
 
112
        if (DEFAULT == null) {
 
113
            String tips = Utils.getVariable("tipsOfTheDay", String.class);
 
114
            if (tips != null) {
 
115
                try {
 
116
                    DEFAULT = new TipOfTheDay(new URL(tips));
 
117
                } catch (MalformedURLException ex) {
 
118
                    LOG.log(Level.WARNING, ex.getMessage(), ex);
 
119
                }
 
120
            }
 
121
            if (DEFAULT == null) {
 
122
                return new TipOfTheDay(null);
 
123
            }
 
124
        }
 
125
        return DEFAULT;
 
126
    }
 
127
 
 
128
    /** Refreshes the content of the databases. Re-reads the content of 
 
129
     * the provided URL and updates internal structures.
 
130
     */
 
131
    public void run() {
 
132
        LOG.info("Refreshing content of TipOfTheDay: " + url); // NOI18N
 
133
        try {
 
134
            Parser p = new Parser();
 
135
            tips = p.parse(url);
 
136
            return;
 
137
        } catch (SAXException ex) {
 
138
            LOG.log(Level.WARNING, ex.getMessage(), ex);
 
139
        } catch (ParserConfigurationException ex) {
 
140
            LOG.log(Level.WARNING, ex.getMessage(), ex);
 
141
        } catch (IOException ex) {
 
142
            LOG.log(Level.WARNING, ex.getMessage(), ex);
 
143
        } finally {
 
144
            LOG.info("Done refreshing of TipOfTheDay"); // NOI18N
 
145
            refresh.schedule(60 * 1000 * 60);
 
146
        }
 
147
    }
 
148
    
 
149
    /** Finds appropriate tip of the date for given usage of projects.
 
150
     * @param cnts collected info from ProjectTypes
 
151
     * @return randomly selected typ
 
152
     */
 
153
    public Tip find(Set<Map.Entry<String,Integer>> cnts) {
 
154
        List<? extends Tip> all = findAll(cnts);
 
155
        if (all.isEmpty()) {
 
156
            return null;
 
157
        }
 
158
        int r = new Random().nextInt(all.size());
 
159
        return all.get(r);
 
160
    }
 
161
    
 
162
    /** Finds all tips appropriate as tip of the date for given usage of projects.
 
163
     * @param cnts the counts
 
164
     * @return list of possible tips
 
165
     */
 
166
    public List<? extends Tip> findAll(Set<Map.Entry<String,Integer>> cnts) {
 
167
        int max = -1;
 
168
        List<Tip> found = Collections.emptyList();
 
169
        if (cnts == null) {
 
170
            return found;
 
171
        }
 
172
        
 
173
        for (Map.Entry<String, Integer> entry : cnts) {
 
174
            if (entry.getValue() > max) {
 
175
                List<Tip> f = tips.get(entry.getKey());
 
176
                if (f != null) {
 
177
                    max = entry.getValue();
 
178
                    found = f;
 
179
                }
 
180
            }
 
181
        }
 
182
        return found;
 
183
    }
 
184
    
 
185
        
 
186
    static String findProject(String category) throws SAXException {
 
187
        String ret = null;
 
188
        if ("Web and Enterprise Development".equals(category)) { // NOI18N
 
189
            ret = "Ear"; // NOI18N
 
190
        }
 
191
        if ("NetBeans Platform Development".equals(category)) { // NOI18N
 
192
            ret = "NbModule"; // NOI18N
 
193
        }
 
194
        if ("Swing GUI Development".equals(category)) { // NOI18N
 
195
            ret = "j2se"; // NOI18N
 
196
        }
 
197
        if ("Monitoring and Profiling".equals(category)) { // NOI18N
 
198
            ret = "profiler";
 
199
        }
 
200
        if ("Mobile Application Development".equals(category)) { // NOI18N
 
201
            ret = "J2ME"; // NOI18N
 
202
        }
 
203
        if ("Advanced and Miscellaneous".equals(category)) { // NOI18N
 
204
            ret = "J2SE"; // NOI18N
 
205
        }
 
206
        if ("Basic IDE Functionality".equals(category)) { // NOI18N
 
207
            ret = "J2SE"; // NOI18N
 
208
        }
 
209
        
 
210
        if (ret == null) {
 
211
            throw new SAXException("Unexpected category: " + category);
 
212
        }
 
213
        return ret;
 
214
    }
 
215
    
 
216
    
 
217
    /** Represents info about one tip.
 
218
     */
 
219
    public static final class Tip {
 
220
        String category;
 
221
        String description;
 
222
        String url;
 
223
        String title;
 
224
        
 
225
        public String getDescription() {
 
226
            return description;
 
227
        }
 
228
        
 
229
        public String getUrl() {
 
230
            return url;
 
231
        }
 
232
        
 
233
        public String getTitle() {
 
234
            return title;
 
235
        }
 
236
    } // end of Tip
 
237
    
 
238
    
 
239
    /* parser for
 
240
        <article>
 
241
                <date>2007-03-05 00:00:00</date>
 
242
                <title>NetBeans IDE 6.0 GUI Builder Demo</title>
 
243
                <description>In this preview the NetBeans IDE 6.0, you will see how much easier it is to develop Java desktop applications with the improved GUI Builder. You'll see the tools which take advantage of both the Swing Application framework(JSR 296) and Beans Binding(JSR 295). Check it out!</description>
 
244
                <category>Swing GUI Development</category>
 
245
                <url>http://www.netbeans.org/download/flash/netbeans_6_gui_builder/netbeans_6_gui_builder.html</url>
 
246
        </article>
 
247
     */
 
248
    private static final class Parser extends DefaultHandler {
 
249
        private Map<String,List<Tip>> tips = new HashMap<String, List<TipOfTheDay.Tip>>();
 
250
        private Tip current;
 
251
        private Queue<StringBuilder> values = new LinkedList<StringBuilder>();
 
252
        
 
253
        public Map<String,List<Tip>> parse(URL url) throws SAXException, ParserConfigurationException, IOException {
 
254
            SAXParserFactory f = SAXParserFactory.newInstance();
 
255
            SAXParser p = f.newSAXParser();
 
256
            InputStream is = url.openStream();
 
257
            p.parse(is, this);
 
258
            is.close();
 
259
            return tips;
 
260
        }
 
261
        
 
262
        @Override
 
263
        public void startElement(String uri, String local, String qName, Attributes args) throws SAXException {
 
264
            if (LOG.isLoggable(Level.FINEST)) {
 
265
                LOG.finest("startElement uri: " + uri + " local: " + local + " qName: " + qName); // NOI18N
 
266
            }
 
267
            if (qName.equals("article")) {
 
268
                assert current == null;
 
269
                current = new Tip();
 
270
            }
 
271
            
 
272
            values.add(new StringBuilder());
 
273
        }
 
274
        
 
275
        @Override
 
276
        public void characters(char[] characters, int from, int len) throws SAXException {
 
277
            assert !values.isEmpty();
 
278
            
 
279
            StringBuilder value = values.peek();
 
280
            if (LOG.isLoggable(Level.FINEST)) {
 
281
                LOG.finest("characters: " + new String(characters, from, len)); // NOI18N
 
282
            }
 
283
            value.append(characters, from, len);
 
284
        }
 
285
 
 
286
        
 
287
        
 
288
        @Override
 
289
        public void endElement(String uri, String local, String qName) throws SAXException {
 
290
            assert !values.isEmpty();
 
291
            
 
292
            StringBuilder value = values.poll();
 
293
            for (int i = 0; i < value.length(); i++) {
 
294
                if (!Character.isWhitespace(value.charAt(i))) {
 
295
                    value.delete(0, i);
 
296
                    break;
 
297
                }
 
298
            }
 
299
            for (int i = value.length() - 1; i > 0; i--) {
 
300
                if (!Character.isWhitespace(value.charAt(i))) {
 
301
                    value.delete(i + 1, value.length());
 
302
                    break;
 
303
                }
 
304
            }
 
305
            
 
306
            if (LOG.isLoggable(Level.FINEST)) {
 
307
                LOG.finest("endElement uri: " + uri + " local: " + local + " qName: " + qName); // NOI18N
 
308
            }
 
309
            if (qName.equals("article")) { // NOI18N
 
310
                assert current != null;
 
311
                String prj = findProject(current.category);
 
312
                List<Tip> arr = tips.get(prj);
 
313
                if (arr == null) {
 
314
                    arr = new ArrayList<Tip>();
 
315
                    tips.put(prj, arr);
 
316
                }
 
317
                arr.add(current);
 
318
                current = null;
 
319
                return;
 
320
            }
 
321
            
 
322
            if (qName.equals("description")) { // NOI18N
 
323
                assert current != null;
 
324
                assert value != null;
 
325
                current.description = value.toString();
 
326
            }
 
327
            
 
328
            if (qName.equals("title")) { // NOI18N
 
329
                assert current != null;
 
330
                assert value != null;
 
331
                current.title = value.toString();
 
332
            }
 
333
 
 
334
            if (qName.equals("url")) { // NOI18N
 
335
                assert current != null;
 
336
                assert value != null;
 
337
                current.url = value.toString();
 
338
            }
 
339
 
 
340
            if (qName.equals("category")) { // NOI18N
 
341
                assert current != null;
 
342
                assert value != null;
 
343
                current.category = value.toString();
 
344
            }
 
345
        }
 
346
    } // end of Parser
 
347
}