Java tutorial
/* * zippyzipjp * * Copyright 2008-2010 Michinobu Maeda. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jp.zippyzip.web; import java.io.IOException; import java.sql.Timestamp; import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.jdo.JDOObjectNotFoundException; import javax.jdo.PersistenceManager; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jp.zippyzip.City; import jp.zippyzip.ParentChild; import jp.zippyzip.Pref; import jp.zippyzip.Zip; import jp.zippyzip.ZipInfo; import org.json.JSONException; import org.json.JSONObject; /** * ?? * * @author Michinobu Maeda */ public class ListServlet extends HttpServlet { /** ?ID? */ private static final long serialVersionUID = -7687570505918475381L; /** JIS X 0401 ? */ private static final Pattern PATTERN_PREF = Pattern.compile("[0-9]{2}"); /** JIS X 0402 ? */ private static final Pattern PATTERN_CITY = Pattern.compile("[0-9]{5}"); /** JIS X 0402 ??1? */ private static final Pattern PATTERN_ADD1 = Pattern.compile("[0-9]{5}\\-.*"); /** JIS X 0402 ? "j" ? */ private static final Pattern PATTERN_CORP = Pattern.compile("[0-9]{5}c"); /** ?? */ private static final Pattern PATTERN_ZIP = Pattern.compile("[0-9]{7}"); /** ? */ private static final String LIST_JSP = "/WEB-INF/views/list.jsp"; /** ? : */ private static final String LISTM_JSP = "/WEB-INF/views/listm.jsp"; /** ? : ? */ private static final String LISTK_JSP = "/WEB-INF/views/listk.jsp"; /** ? */ private static final String SAMPLE_JSP = "/WEB-INF/views/jquerysample.jsp"; /** ? */ private static final String SAMPLEA_JSP = "/WEB-INF/views/jquerysamplea.jsp"; /** ? */ private static final String SAMPLEZ_JSP = "/WEB-INF/views/jquerysamplez.jsp"; /** ? */ private static final String PATH_DEF = "/list/prefs"; /** */ private static final String PAGE_TITLE = "?"; /** */ protected Logger log = Logger.getLogger(this.getClass().getName()); { log.setLevel(Level.INFO); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getPathInfo(); String redirect = null; if ((path == null) || path.equals("") || path.equals("/")) { response.sendRedirect(PATH_DEF); return; } else { path = path.replace("/", ""); } if (path.equals("jquerysample")) { getServletContext().getRequestDispatcher(SAMPLE_JSP).forward(request, response); return; } if (path.equals("jquerysamplea")) { getServletContext().getRequestDispatcher(SAMPLEA_JSP).forward(request, response); return; } if (path.equals("jquerysamplez")) { getServletContext().getRequestDispatcher(SAMPLEZ_JSP).forward(request, response); return; } if (path.equals("lastUpdate")) { PersistenceManager pm = PMF.get().getPersistenceManager(); try { for (ZipInfo zipInfo : pm.getExtent(ZipInfo.class)) { response.getWriter().print(zipInfo.getGenerated().toString()); break; } } finally { pm.close(); } return; } final String add1Code; final String key; String val = path.endsWith(".json") ? path.substring(0, path.length() - 5) : path; if (val.contains("-")) { key = val.substring(0, val.indexOf("-")); add1Code = val.substring(val.indexOf("-") + 1); } else { key = val; add1Code = null; } PersistenceManager pm = PMF.get().getPersistenceManager(); try { ParentChild data = null; try { if (PATTERN_ZIP.matcher(key).matches()) { data = pm.getObjectById(ParentChild.class, key.substring(0, 3)); } else { data = pm.getObjectById(ParentChild.class, key); } data.getChildren().size(); } catch (JDOObjectNotFoundException e) { } if (path.endsWith(".json")) { response.setContentType("text/json"); response.setCharacterEncoding("UTF-8"); final String ret; if (data == null) { ret = "{}"; } else if (key.equals("prefs")) { ret = toJsonPrefs(data); } else if (PATTERN_PREF.matcher(key).matches()) { ret = toJsonCities(data); } else if (PATTERN_CITY.matcher(key).matches()) { if (add1Code == null) { ret = toJsonAdd1s(data); } else { ret = toJsonAdd2s(data, add1Code); } } else if (PATTERN_CORP.matcher(key).matches()) { ret = toJsonCorps(data); } else if (PATTERN_ZIP.matcher(key).matches()) { ret = toJsonZips(data, key, pm); } else { ret = "{}"; } response.getWriter().print(ret); } else { String userAgent = request.getHeader("User-Agent"); String jsp = LIST_JSP; request.setAttribute("path", request.getPathInfo()); if (!userAgent.toLowerCase().contains("mozilla")) { jsp = LISTK_JSP; } else if (userAgent.toLowerCase().contains("mobile")) { jsp = LISTM_JSP; } if (path.equals("prefs")) { setPrefs(request, data); } else if (PATTERN_PREF.matcher(path).matches()) { if (data == null) { redirect = PATH_DEF; } else { setCities(request, data); } } else if (PATTERN_CITY.matcher(path).matches()) { if (data == null) { redirect = "/list/" + path.substring(0, 2); } else { setAdd1s(request, data); } } else if (PATTERN_ADD1.matcher(path).matches()) { if (data == null) { redirect = "/list/" + path.substring(0, 5); } else { setAdd2s(request, data, fromHex(add1Code)); } } else if (PATTERN_CORP.matcher(path).matches()) { if (data == null) { redirect = "/list/" + path.substring(0, 2); } else { setCorp(request, data); } } else if (path.equals("building")) { if (data == null) { redirect = "/list/"; } else { SortedMap<String, Pref> prefs = getPrefMap(pm); SortedMap<String, City> cities = getCityMap(pm, prefs); setBuilding(request, data, prefs, cities); } } else { redirect = PATH_DEF; } if (redirect == null) { getServletContext().getRequestDispatcher(jsp).forward(request, response); } } } catch (JSONException e) { log.log(Level.WARNING, "", e); } finally { pm.close(); } if (redirect != null) { response.sendRedirect(redirect); } } void setPrefs(HttpServletRequest request, ParentChild data) throws JSONException { LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); breadCrumbs.add(new BreadCrumb(null, PAGE_TITLE)); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", ""); for (String json : data.getChildren()) { Pref pref = Pref.fromJson(json); list.add(new ListItem(pref.getCode(), null, null, pref.getName(), pref.getYomi(), "")); } list.add(new ListItem("building", null, null, "??", "", "")); request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } void setCities(HttpServletRequest request, ParentChild data) throws JSONException { LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); long timestamp = new Date().getTime(); Pref pref = Pref.fromJson(data.getParents().getFirst()); breadCrumbs.add(new BreadCrumb("prefs", PAGE_TITLE)); breadCrumbs.add(new BreadCrumb(null, pref.getName())); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", ""); for (String json : data.getChildren()) { City city = City.fromJson(json); boolean expired = (city.getExpiration().getTime() < timestamp); list.add(new ListItem(city.getCode() + (expired ? "c" : ""), null, null, city.getName(), city.getYomi(), (expired ? "" : ""))); } request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } void setAdd1s(HttpServletRequest request, ParentChild data) throws JSONException { LinkedList<Zip> zips = new LinkedList<Zip>(); Set<String> add1s = new HashSet<String>(); Set<String> add2s = new HashSet<String>(); Set<String> add2hit = new HashSet<String>(); LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); Pref pref = Pref.fromJson(data.getParents().getFirst()); City self = City.fromJson(data.getParents().getLast()); breadCrumbs.add(new BreadCrumb("prefs", PAGE_TITLE)); breadCrumbs.add(new BreadCrumb(pref.getCode(), pref.getName())); breadCrumbs.add(new BreadCrumb(null, self.getName() + "(?)")); breadCrumbs.add(new BreadCrumb(self.getCode() + "c", "()")); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", ""); for (String json : data.getChildren()) { Zip zip = Zip.fromJson(json); zips.add(zip); if (add1s.add(zip.getAdd1())) { continue; } add2s.add(zip.getAdd1()); } for (Zip zip : zips) { if (add2s.contains(zip.getAdd1())) { if (!add2hit.contains(zip.getAdd1())) { list.add(new ListItem(zip.getX0402() + "-" + toHex(zip.getAdd1()), null, null, zip.getAdd1(), zip.getAdd1Yomi(), null)); add2hit.add(zip.getAdd1()); } } else { list.add(new ListItem(null, zip.getCode().substring(0, 3), zip.getCode().substring(3), zip.getAdd1() + zip.getAdd2(), zip.getAdd1Yomi() + zip.getAdd2Yomi(), zip.getNote())); } } request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } void setBuilding(HttpServletRequest request, ParentChild data, SortedMap<String, Pref> prefs, SortedMap<String, City> cities) throws JSONException { LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); String x0402 = ""; breadCrumbs.add(new BreadCrumb("prefs", PAGE_TITLE)); breadCrumbs.add(new BreadCrumb(null, "??")); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", ""); for (String json : data.getChildren()) { Zip zip = Zip.fromJson(json); if (!x0402.equals(zip.getX0402())) { x0402 = zip.getX0402(); list.add(new ListItem(null, "", "", prefs.get(x0402.subSequence(0, 2)).getName() + "" + cities.get(x0402).getName(), "", "")); } int sep = zip.getAdd1().indexOf(" "); String add1 = (sep < 0) ? "" : zip.getAdd1().substring(0, sep); String name = zip.getAdd1().substring(sep + 1); sep = zip.getAdd1Yomi().indexOf(" "); list.add(new ListItem(zip.getX0402() + "-" + toHex(add1 + name), null, null, name, zip.getAdd1Yomi().substring(sep + 1), null)); } request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } void setAdd2s(HttpServletRequest request, ParentChild data, String add1) throws JSONException { LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); Pref pref = Pref.fromJson(data.getParents().getFirst()); City self = City.fromJson(data.getParents().getLast()); breadCrumbs.add(new BreadCrumb("prefs", PAGE_TITLE)); breadCrumbs.add(new BreadCrumb(pref.getCode(), pref.getName())); breadCrumbs.add(new BreadCrumb(self.getCode(), self.getName())); breadCrumbs.add(new BreadCrumb(null, add1)); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", ""); for (String json : data.getChildren()) { Zip zip = Zip.fromJson(json); if (!add1.equals(zip.getAdd1())) { continue; } list.add(new ListItem(null, zip.getCode().substring(0, 3), zip.getCode().substring(3), zip.getAdd2(), zip.getAdd2Yomi(), zip.getNote())); } request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } void setCorp(HttpServletRequest request, ParentChild data) throws JSONException { LinkedList<ListItem> list = new LinkedList<ListItem>(); LinkedList<BreadCrumb> breadCrumbs = new LinkedList<BreadCrumb>(); Pref pref = Pref.fromJson(data.getParents().getFirst()); City self = City.fromJson(data.getParents().getLast()); breadCrumbs.add(new BreadCrumb("prefs", PAGE_TITLE)); breadCrumbs.add(new BreadCrumb(pref.getCode(), pref.getName())); breadCrumbs.add(new BreadCrumb(null, self.getName() + "()")); breadCrumbs.add(new BreadCrumb(self.getCode(), "(?)")); request.setAttribute("breadCrumbs", breadCrumbs); request.setAttribute("br", "<br />"); for (String json : data.getChildren()) { Zip zip = Zip.fromJson(json); list.add(new ListItem(null, zip.getCode().substring(0, 3), zip.getCode().substring(3), zip.getCorp(), zip.getCorpYomi(), zip.getAdd1() + zip.getAdd2())); } request.setAttribute("list", list); request.setAttribute("timestamp", data.getTimestamp()); } String toHex(String str) { StringBuilder ret = new StringBuilder(); for (int i = 0; i < str.length(); ++i) { ret.append(String.format("%04x", (int) str.charAt(i))); } return ret.toString(); } String fromHex(String hex) { StringBuilder ret = new StringBuilder(); for (int i = 0; i < hex.length(); i += 4) { try { ret.append((char) Integer.parseInt(hex.substring(i, i + 4), 16)); } catch (NumberFormatException e) { log.warning(e.getMessage() + " : \"" + hex.substring(i, i + 4) + "\""); } } return ret.toString(); } String toJsonPrefs(ParentChild data) throws JSONException { StringBuilder ret = new StringBuilder("{\"prefs\":["); boolean start = true; for (String json : data.getChildren()) { if (start) { start = false; } else { ret.append(","); } JSONObject jo = new JSONObject(json); jo.remove("yomi"); ret.append(jo.toString()); } return ret.append("]}").toString(); } String toJsonCities(ParentChild data) throws JSONException { boolean start = true; JSONObject pref = new JSONObject(data.getParents().getFirst()); StringBuilder ret = new StringBuilder("{\"pref\":"); pref.remove("yomi"); ret.append(pref.toString()); ret.append(",\"cities\":["); for (String json : data.getChildren()) { if (start) { start = false; } else { ret.append(","); } JSONObject jo = new JSONObject(json); if (Timestamp.valueOf(jo.getString("expiration")).getTime() < new Date().getTime()) { jo.put("note", ""); } jo.remove("yomi"); jo.remove("expiration"); ret.append(jo.toString()); } return ret.append("]}").toString(); } String toJsonAdd1s(ParentChild data) throws JSONException { LinkedList<String> zips = new LinkedList<String>(); Set<String> add1s = new HashSet<String>(); Set<String> add2s = new HashSet<String>(); Set<String> add2hit = new HashSet<String>(); boolean start = true; JSONObject pref = new JSONObject(data.getParents().getFirst()); JSONObject city = new JSONObject(data.getParents().getLast()); StringBuilder ret = new StringBuilder("{\"pref\":"); pref.remove("yomi"); ret.append(pref.toString()); ret.append(",\"city\":"); city.remove("yomi"); city.remove("expiration"); ret.append(city.toString()); ret.append(",\"zips\":["); for (String json : data.getChildren()) { String add1 = new JSONObject(json).optString("add1", ""); zips.add(json); if (add1s.add(add1)) { continue; } add2s.add(add1); } for (String json : zips) { JSONObject jo = new JSONObject(json); String add1 = jo.optString("add1", ""); jo.remove("x0402"); jo.remove("corp"); jo.remove("add1Yomi"); jo.remove("add2Yomi"); jo.remove("corpYomi"); if (add2s.contains(add1)) { if (!add2hit.contains(add1)) { if (start) { start = false; } else { ret.append(","); } jo.remove("code"); jo.remove("add2"); jo.remove("note"); jo.put("code", toHex(add1)); ret.append(jo.toString()); add2hit.add(add1); } } else { if (start) { start = false; } else { ret.append(","); } String zip = jo.optString("code", ""); jo.remove("code"); jo.put("zip1", zip.substring(0, 3)); jo.put("zip2", zip.substring(3)); ret.append(jo.toString()); } } return ret.append("]}").toString(); } String toJsonAdd2s(ParentChild data, String code) throws JSONException { boolean start = true; JSONObject pref = new JSONObject(data.getParents().getFirst()); JSONObject city = new JSONObject(data.getParents().getLast()); String name = fromHex(code); StringBuilder ret = new StringBuilder("{\"pref\":"); pref.remove("yomi"); ret.append(pref.toString()); ret.append(",\"city\":"); city.remove("yomi"); city.remove("expiration"); ret.append(city.toString()); ret.append(",\"add1\":{\"code\":\""); ret.append(code); ret.append("\",\"name\":\""); ret.append(name); ret.append("\"},\"zips\":["); for (String json : data.getChildren()) { JSONObject jo = new JSONObject(json); String add1 = jo.optString("add1", ""); if (!name.equals(add1)) { continue; } if (start) { start = false; } else { ret.append(","); } String zip = jo.optString("code", ""); jo.remove("code"); jo.put("zip1", zip.substring(0, 3)); jo.put("zip2", zip.substring(3)); jo.remove("x0402"); jo.remove("corp"); jo.remove("add1"); jo.remove("add1Yomi"); jo.remove("add2Yomi"); jo.remove("corpYomi"); ret.append(jo.toString()); } return ret.append("]}").toString(); } String toJsonCorps(ParentChild data) throws JSONException { boolean start = true; StringBuilder ret = new StringBuilder("{\"pref\":"); JSONObject pref = new JSONObject(data.getParents().getFirst()); JSONObject city = new JSONObject(data.getParents().getLast()); pref.remove("yomi"); ret.append(pref.toString()); ret.append(",\"city\":"); city.remove("yomi"); city.remove("expiration"); ret.append(city.toString()); ret.append(",\"zips\":["); for (String json : data.getChildren()) { if (start) { start = false; } else { ret.append(","); } JSONObject jo = new JSONObject(json); String code = jo.optString("code", ""); jo.remove("code"); jo.remove("x0402"); jo.remove("corpYomi"); jo.put("zip1", code.substring(0, 3)); jo.put("zip2", code.substring(3)); ret.append(jo.toString()); } return ret.append("]}").toString(); } String toJsonZips(ParentChild data, String zip, PersistenceManager pm) throws JSONException { String zip2 = zip.substring(3); SortedSet<String> keys = new TreeSet<String>(); boolean start = true; StringBuilder ret = new StringBuilder("{\"zip1\":\""); ret.append(data.getParents().getFirst()); ret.append("\",\"zip2\":\""); ret.append(zip2); ret.append("\",\"zips\":["); for (String json : data.getChildren()) { JSONObject jo = new JSONObject(json); if (!jo.optString("zip2", "").equals(zip2)) { continue; } keys.add(jo.optString("key", "")); } for (String key : keys) { try { ParentChild zips = pm.getObjectById(ParentChild.class, key); City city = City.fromJson(zips.getParents().getLast()); for (String json : zips.getChildren()) { JSONObject jo = new JSONObject(json); if (!jo.optString("code", "").equals(zip)) { continue; } if (start) { start = false; } else { ret.append(","); } jo.put("x0402", city.getCode()); jo.put("city", city.getName()); jo.remove("add1Yomi"); jo.remove("add2Yomi"); jo.remove("corpYomi"); ret.append(jo.toString()); } } catch (JDOObjectNotFoundException e) { } } return ret.append("]}").toString(); } /** * ???? * * @return ?? */ SortedMap<String, Pref> getPrefMap(PersistenceManager pm) { SortedMap<String, Pref> ret = new TreeMap<String, Pref>(); for (String json : pm.getObjectById(ParentChild.class, "prefs").getChildren()) { Pref pref = Pref.fromJson(json); ret.put(pref.getCode(), pref); } return ret; } /** * ???? * * @return ?? */ SortedMap<String, City> getCityMap(PersistenceManager pm, SortedMap<String, Pref> prefs) { SortedMap<String, City> ret = new TreeMap<String, City>(); for (Pref pref : prefs.values()) { ParentChild pc = pm.getObjectById(ParentChild.class, pref.getCode()); if (pc == null) { continue; } for (String json : pc.getChildren()) { City city = City.fromJson(json); ret.put(city.getCode(), city); } } return ret; } }