1 19 package org.netbeans.server.uihandler; 20 21 import org.netbeans.server.uihandler.statistics.*; 22 import org.netbeans.server.uihandler.*; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.net.MalformedURLException ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.Collections ; 29 import java.util.HashMap ; 30 import java.util.LinkedList ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Queue ; 34 import java.util.Random ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 import javax.xml.parsers.ParserConfigurationException ; 38 import javax.xml.parsers.SAXParser ; 39 import javax.xml.parsers.SAXParserFactory ; 40 import org.openide.util.Exceptions; 41 import org.openide.util.RequestProcessor; 42 import org.xml.sax.Attributes ; 43 import org.xml.sax.SAXException ; 44 import org.xml.sax.helpers.DefaultHandler ; 45 46 52 public final class TipOfTheDay implements Runnable { 53 private static final Logger LOG = Logger.getLogger(TipOfTheDay.class.getName()); 54 private static RequestProcessor RP = new RequestProcessor("Refresh TipOfTheDay"); 55 56 private Map <String ,List <Tip>> tips; 57 private final URL url; 58 private RequestProcessor.Task refresh; 59 60 private TipOfTheDay(URL url) { 61 this.url = url; 62 if (url == null) { 63 tips = Collections.emptyMap(); 64 return; 65 } 66 tips = Collections.emptyMap(); 67 68 refresh = RP.create(this); 69 refresh.schedule(0); 70 71 try { 72 refresh.waitFinished(10000); 73 } catch (InterruptedException ex) { 74 LOG.log(Level.WARNING, ex.getMessage(), ex); 75 } 76 } 77 78 81 public static TipOfTheDay create(URL url) { 82 return new TipOfTheDay(url); 83 } 84 85 private static TipOfTheDay DEFAULT; 86 88 public static TipOfTheDay getDefault() { 89 if (DEFAULT == null) { 90 String tips = Utils.getVariable("tipsOfTheDay", String .class); 91 if (tips != null) { 92 try { 93 DEFAULT = new TipOfTheDay(new URL (tips)); 94 } catch (MalformedURLException ex) { 95 LOG.log(Level.WARNING, ex.getMessage(), ex); 96 } 97 } 98 if (DEFAULT == null) { 99 return new TipOfTheDay(null); 100 } 101 } 102 return DEFAULT; 103 } 104 105 108 public void run() { 109 LOG.info("Refreshing content of TipOfTheDay: " + url); try { 111 Parser p = new Parser (); 112 tips = p.parse(url); 113 return; 114 } catch (SAXException ex) { 115 LOG.log(Level.WARNING, ex.getMessage(), ex); 116 } catch (ParserConfigurationException ex) { 117 LOG.log(Level.WARNING, ex.getMessage(), ex); 118 } catch (IOException ex) { 119 LOG.log(Level.WARNING, ex.getMessage(), ex); 120 } finally { 121 LOG.info("Done refreshing of TipOfTheDay"); refresh.schedule(60 * 1000 * 60); 123 } 124 } 125 126 130 public Tip find(ProjectTypes.Counts cnts) { 131 List <? extends Tip> all = findAll(cnts); 132 if (all.isEmpty()) { 133 return null; 134 } 135 int r = new Random ().nextInt(all.size()); 136 return all.get(r); 137 } 138 139 141 public List <? extends Tip> findAll(ProjectTypes.Counts cnts) { 142 int max = -1; 143 List <Tip> found = Collections.emptyList(); 144 if (cnts == null) { 145 return found; 146 } 147 148 for (Map.Entry <String , Integer > entry : cnts.getUsages()) { 149 if (entry.getValue() > max) { 150 List <Tip> f = tips.get(entry.getKey()); 151 if (f != null) { 152 max = entry.getValue(); 153 found = f; 154 } 155 } 156 } 157 return found; 158 } 159 160 161 static String findProject(String category) throws SAXException { 162 String ret = null; 163 if ("Web and Enterprise Development".equals(category)) { ret = "Ear"; } 166 if ("NetBeans Platform Development".equals(category)) { ret = "NbModule"; } 169 if ("Swing GUI Development".equals(category)) { ret = "j2se"; } 172 if ("Monitoring and Profiling".equals(category)) { ret = "profiler"; 174 } 175 if ("Mobile Application Development".equals(category)) { ret = "J2ME"; } 178 if ("Advanced and Miscellaneous".equals(category)) { ret = "J2SE"; } 181 if ("Basic IDE Functionality".equals(category)) { ret = "J2SE"; } 184 185 if (ret == null) { 186 throw new SAXException ("Unexpected category: " + category); 187 } 188 return ret; 189 } 190 191 192 194 public static final class Tip { 195 String category; 196 String description; 197 String url; 198 String title; 199 200 public String getDescription() { 201 return description; 202 } 203 204 public String getUrl() { 205 return url; 206 } 207 208 public String getTitle() { 209 return title; 210 } 211 } 213 214 223 private static final class Parser extends DefaultHandler { 224 private Map <String ,List <Tip>> tips = new HashMap <String , List <TipOfTheDay.Tip>>(); 225 private Tip current; 226 private Queue <StringBuilder > values = new LinkedList <StringBuilder >(); 227 228 public Map <String ,List <Tip>> parse(URL url) throws SAXException , ParserConfigurationException , IOException { 229 SAXParserFactory f = SAXParserFactory.newInstance(); 230 SAXParser p = f.newSAXParser(); 231 InputStream is = url.openStream(); 232 p.parse(is, this); 233 is.close(); 234 return tips; 235 } 236 237 @Override 238 public void startElement(String uri, String local, String qName, Attributes args) throws SAXException { 239 if (LOG.isLoggable(Level.FINEST)) { 240 LOG.finest("startElement uri: " + uri + " local: " + local + " qName: " + qName); } 242 if (qName.equals("article")) { 243 assert current == null; 244 current = new Tip(); 245 } 246 247 values.add(new StringBuilder ()); 248 } 249 250 @Override 251 public void characters(char[] characters, int from, int len) throws SAXException { 252 assert !values.isEmpty(); 253 254 StringBuilder value = values.peek(); 255 if (LOG.isLoggable(Level.FINEST)) { 256 LOG.finest("characters: " + new String (characters, from, len)); } 258 value.append(characters, from, len); 259 } 260 261 262 263 @Override 264 public void endElement(String uri, String local, String qName) throws SAXException { 265 assert !values.isEmpty(); 266 267 StringBuilder value = values.poll(); 268 for (int i = 0; i < value.length(); i++) { 269 if (!Character.isWhitespace(value.charAt(i))) { 270 value.delete(0, i); 271 break; 272 } 273 } 274 for (int i = value.length() - 1; i > 0; i--) { 275 if (!Character.isWhitespace(value.charAt(i))) { 276 value.delete(i + 1, value.length()); 277 break; 278 } 279 } 280 281 if (LOG.isLoggable(Level.FINEST)) { 282 LOG.finest("endElement uri: " + uri + " local: " + local + " qName: " + qName); } 284 if (qName.equals("article")) { assert current != null; 286 String prj = findProject(current.category); 287 List <Tip> arr = tips.get(prj); 288 if (arr == null) { 289 arr = new ArrayList <Tip>(); 290 tips.put(prj, arr); 291 } 292 arr.add(current); 293 current = null; 294 return; 295 } 296 297 if (qName.equals("description")) { assert current != null; 299 assert value != null; 300 current.description = value.toString(); 301 } 302 303 if (qName.equals("title")) { assert current != null; 305 assert value != null; 306 current.title = value.toString(); 307 } 308 309 if (qName.equals("url")) { assert current != null; 311 assert value != null; 312 current.url = value.toString(); 313 } 314 315 if (qName.equals("category")) { assert current != null; 317 assert value != null; 318 current.category = value.toString(); 319 } 320 } 321 } } 323 | Popular Tags |