package yoonforh.bbs; /** * BBSUtil.java * Copyright (c) 1997-1998 Yoon Kyung Koo. All rights reserved. * * contact via yoonforh@moon.daewoo.co.kr * * first release (ver. 0.01) date 1997/10/07 * * @version 1.2a 1998/06/04 * @author Yoon Kyung Koo */ import java.io.*; import java.util.*; import java.text.*; import java.net.*; import javax.servlet.*; import javax.servlet.http.*; /** * BBSUtil class * This class holds several information about this service-specific path names * and several common methods. */ class BBSUtil { /* these values can be initialized from init parameter of servlet */ private static String dataDir="C:/bbs_data/"; private static String masterKey="password"; /* these values are fixed for convenience */ private static final String printURL="/servlet/BBSPrint"; // yoonforh.bbs.PrintServlet private static final String listURL="/servlet/BBSList"; // yoonforh.bbs.ListServlet private static final String editURL="/servlet/BBSEdit"; // yoonforh.bbs.EditServlet private static final String editResultURL="/servlet/BBSEditResult"; // yoonforh.bbs.EditResultServlet private static final String adminEditURL="/servlet/BBSAdminEdit"; // yoonforh.bbs.AdminEditServlet private static final String adminEditChallengeURL="/servlet/BBSAdminEditChallenge"; // yoonforh.bbs.AdminEditChallengeServlet private static final String adminEditResultURL="/servlet/BBSAdminEditResult"; // yoonforh.bbs.AdminEditResultServlet private static final String deleteURL="/servlet/BBSDelete"; // yoonforh.bbs.DeleteServlet private static final String deleteResultURL="/servlet/BBSDeleteResult"; // yoonforh.bbs.DeleteResultServlet private static final String postURL="/servlet/BBSPost"; // yoonforh.bbs.PostServlet private static final String postResultURL="/servlet/BBSPostResult"; // yoonforh.bbs.PostResultServlet private static final String homeURL="/bbs"; // root home directory private static final String homeImageURL="/images/home.jpg"; private static final String docuImageURL="/images/document.gif"; // prefer transparent gif private static final String threadImageURL="/images/thread.gif"; // prefer transparent gif private static final String bodyStatement=""; private static final String countFile="BBS_counter"; /** * setInitParameters() * this method set init parameters * @param String dataDir root directory to save data * @param String masterKey master password */ static void setInitParameters(String dataDir, String masterKey) { if (dataDir!=null) BBSUtil.dataDir=dataDir; if (masterKey!=null) BBSUtil.masterKey=masterKey; } /** * getCount() * this method returns current number of data files * @param String category to specify bbs * @return current number of data files(articles) * @exception java.io.IOException */ private synchronized static int getCount(String category) throws IOException { int count; RandomAccessFile file=new RandomAccessFile(new File(dataDir+category+"/"+countFile), "rw"); try { file.seek(0); // set file pointer to beginning try { count=file.readInt(); } catch (IOException ie) { // case no data try { file.writeInt(0); count=0; } catch (IOException ie2) { throw ie2; } } } finally { file.close(); } return count; } // end of getCount() /** * addCount() * this method increases current number of data files * @param String category to specify bbs * @exception java.io.IOException */ private synchronized static void addCount(String category) throws IOException { int count; RandomAccessFile file=new RandomAccessFile(new File(dataDir+category+"/"+countFile), "rw"); try { file.seek(0); // set file pointer to beginning try { count=file.readInt(); } catch (IOException ie) { // case no data try { file.writeInt(0); count=0; } catch (IOException ie2) { throw ie2; } } count++; file.seek(0); // set file pointer to beginning file.writeInt(count); } finally { file.close(); } } // end of addCount() /** * addNextNumber() * this method add a number to prev article's next numbers * @param String category to specify bbs * @param int prev article number * @param int new article number * @return boolean if succeed then true, else false * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ synchronized static boolean addNextNumber(String category, int prevNo, int newNo) throws IOException { BBSData data=null; String fileName=dataDir+category+"/"+prevNo+".dat"; try { data=readData(category, prevNo); } catch (IOException ie) { return false; } if (data==null) return false; data.nextNumbers.addElement(new Integer(newNo)); if (!replaceData(category, data)) return false; return true; } // end of addNextNumber /** * writeData() * this method writes data object into specified file * @param String category to specify bbs * @param BBSData data file to write into file * @return numbers of current articles * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ synchronized static int writeData(String category, BBSData data) throws IOException { // serializing String fileName=null; int count=0; count=getCount(category) + 1; fileName=dataDir+category+"/"+count+".dat"; FileOutputStream f_out=new FileOutputStream(fileName); ObjectOutput s_out=new ObjectOutputStream(f_out); data.articleNo=count; try { /* update previous data's nextNumbers */ if (data.prevNo>0) addNextNumber(category, data.prevNo, data.articleNo); s_out.writeObject(data); s_out.flush(); } finally { s_out.close(); f_out.close(); } addCount(category); return count; } // end of writeData() /** * updateDataWithAuth() * this method writes data object into specified file * @param String category to specify bbs * @param BBSData data file to write into file * @return boolean if succeed then true, else if password mismatch then false * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ private synchronized static boolean updateDataWithAuth(String category, BBSData data) throws IOException { int count=data.articleNo; String fileName=dataDir+category+"/"+count+".dat"; BBSData oldData=readData(category, count); if (!data.passwd.equals(oldData.passwd) && !data.passwd.equals(masterKey)) return false; if (data.passwd.equals(masterKey)) // when masterKey used, clear password data.passwd=null; FileOutputStream f_out=new FileOutputStream(fileName); ObjectOutput s_out=new ObjectOutputStream(f_out); try { s_out.writeObject(data); s_out.flush(); } finally { s_out.close(); f_out.close(); } return true; } // end of updateDataWithAuth() /** * replaceData() * this method simply overwrites an existing file with specified data * @param String category to specify bbs * @param BBSData data file to write into file * @return boolean if succeed then true, else if password mismatch then false * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ private synchronized static boolean replaceData(String category, BBSData data) throws IOException { int count=data.articleNo; String fileName=dataDir+category+"/"+count+".dat"; FileOutputStream f_out=new FileOutputStream(fileName); ObjectOutput s_out=new ObjectOutputStream(f_out); try { s_out.writeObject(data); s_out.flush(); } finally { s_out.close(); f_out.close(); } return true; } // end of replaceData() /** * removeData() * this method deletes data object file * @param String category to specify bbs * @param number article number to delete * @return boolean if succeed to delete file then true, otherwise false */ private synchronized static boolean removeData(String category, int number) { String fileName=null; BBSData data=null; try { data=readData(category, number); } catch (IOException ie) {} if (data == null) return false; /* if child data exist ... */ if (data.nextNumbers !=null && !data.nextNumbers.isEmpty()) { for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNo=((Integer) enum.nextElement()).intValue(); try { BBSData nextData=readData(category, nextNo); if (nextData==null) continue; nextData.prevNo=data.prevNo; // replace next data's prev number with data's prev number replaceData(category, nextData); } catch (IOException ie) {} // ignore update-next-file error } } /* if parent data exist ... */ if (data.prevNo>0) { try { BBSData prevData=readData(category, data.prevNo); if (prevData!=null && prevData.nextNumbers!=null && !prevData.nextNumbers.isEmpty() ) // NOTE: removeElement() finds the object using equals() method if (prevData.nextNumbers.removeElement(new Integer(number))) { /* add next elements to prev data */ /* if child data exist ... */ if (data.nextNumbers !=null && !data.nextNumbers.isEmpty()) { for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { prevData.nextNumbers.addElement((Integer) enum.nextElement()); } } replaceData(category, prevData); } } catch (IOException ie) {} // ignore update-prev-file error } fileName=dataDir+category+"/"+number+".dat"; File file=new File(fileName); return file.delete(); } // end of removeData() /** * getGetData() * this method read data object from POST/GET request * @param HttpServletRequest req stream to read * @param boolean isForUpdate specify if this is for update procedure * @return BBSData object read from stream * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static BBSData getGetData(HttpServletRequest req, boolean isForUpdate) throws ServletException, IOException { BBSData data=null; if (isForUpdate) { String category=req.getParameter("cate"); int articleNo=-1; try { articleNo=Integer.parseInt(req.getParameter("number")); } catch (NumberFormatException nfe) {} data=readData(category, articleNo); } else data=new BBSData(); data.name=req.getParameter("NAME_FIELD"); data.passwd=req.getParameter("PASSWORD_FIELD"); String string=req.getParameter("WEB_FIELD"); if (string.equals("")) { data.webAddress=null; } else { try { data.webAddress=new URL(string); } catch (MalformedURLException me) { try { data.webAddress=new URL("http://"+string); } catch (MalformedURLException me2) { data.webAddress=null; } } } string=req.getParameter("EMAIL_FIELD"); if (string.equals("")) { data.emailAddress=null; } else { try { data.emailAddress=new URL(req.getParameter("EMAIL_FIELD")); } catch (MalformedURLException me) { try { data.emailAddress=new URL("mailto:"+req.getParameter("EMAIL_FIELD")); } catch (MalformedURLException me2) { data.emailAddress=null; } } } data.title=req.getParameter("TITLE_FIELD"); data.data=req.getParameter("COMMENT_FIELD"); data.logDate=new Date(System.currentTimeMillis()); String replyTo=req.getParameter("replyto"); try { data.prevNo=(replyTo==null?-1:Integer.parseInt(replyTo)); } catch (NumberFormatException nfe) {} return data; } // end of getGetData() /** * getGetData() * this method read data object from POST/GET request to show article * @param HttpServletRequest req stream to read * @return BBSData object read from stream * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static BBSData getGetData(HttpServletRequest req) throws ServletException, IOException { return getGetData(req, false); } /** * getGetDataForUpdate() * this method read data object from POST/GET request for update * @param HttpServletRequest req stream to read * @return BBSData object read from stream * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static BBSData getGetDataForUpdate(HttpServletRequest req) throws ServletException, IOException { return getGetData(req, true); } /** * getAdminGetData() * this method read data object from POST/GET request for adminer's article edit * @param HttpServletRequest req stream to read * @return BBSData object read from stream * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static BBSData getAdminGetData(HttpServletRequest req) throws ServletException, IOException { BBSData data=getGetData(req, true); String replyTo=req.getParameter("replyto"); try { data.prevNo=(replyTo==null?-1:Integer.parseInt(replyTo)); } catch (NumberFormatException nfe) {} String nexts=req.getParameter("nexts"); if (nexts != null) { data.nextNumbers.removeAllElements(); StringTokenizer token = new StringTokenizer(nexts, ","); while (token.hasMoreTokens()) { try { String nextNo = token.nextToken(); data.nextNumbers.addElement(new Integer(nextNo)); } catch (NumberFormatException nfe) {} } } else data.nextNumbers=null; return data; } /** * readData() * this method read data object * @param String category to specify bbs * @param count specify which file (nth article) to read * @return BBSData object read from data file * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static BBSData readData(String category, int count) throws IOException { // de-serialize BBSData data=null; boolean isAccurateNumber=true; if (count<0) { // -1 means last article count=getCount(category); isAccurateNumber=false; } String fileName=dataDir+category+"/"+count+".dat"; FileInputStream f_in=null; boolean notFound=true; while (notFound) { try { f_in=new FileInputStream(fileName); } catch (FileNotFoundException fe) { if (isAccurateNumber) return null; count-=1; if (count<=0) return null; fileName=dataDir+category+"/"+count+".dat"; continue; } notFound=false; } ObjectInput s_in=new ObjectInputStream(f_in); try { data=(BBSData) s_in.readObject(); } catch (ClassNotFoundException cnfe) { data=null; } finally { s_in.close(); f_in.close(); } return data; } // end of readData() /** * readPrevArticle() * this method read data objects * @param String category to specify bbs * @param articleNo specify from which file (nth article) to read * @param nItems specify number of file to read * @return Vector of BBSData objects * @see yoonforh.bbs.BBSData */ private static Vector readPrevArticle(String category, int articleNo, int nItems) { BBSData data=null; Vector vector = new Vector(); int count=0; for (int i=0; (count=0); i++) { try { data=readData(category, articleNo-i); if (data != null && data.prevNo<0 /* if thread-beginning article */) { vector.addElement(data); count++; } } catch (IOException ie) { } } return vector; } // end of readPrevArticle() /** * readNextArticle() * this method read data objects * @param String category to specify bbs * @param articleNo specify from which file (nth article) to read * @param nItems specify number of file to read * @param maxCount number of all articles * @return Vector of BBSData objects * @see yoonforh.bbs.BBSData */ private static Vector readNextArticle(String category, int articleNo, int nItems, int maxCount) { BBSData data=null; Vector vector = new Vector(); int count=0; for (int i=articleNo; (count and tags * @param ServletOutputStream output stream to print * @param String title title of this document * @exception java.io.IOException */ static void printTitle(ServletOutputStream out, String title) throws IOException { out.println("<HTML><HEAD>"); out.println("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=EUC-KR\">"); out.println("<TITLE>"+title+""); out.println(bodyStatement); } /** * printArticleHeader() * this method prints article's header * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number * @exception java.io.IOException */ static void printArticleHeader(ServletOutputStream out, String category, int articleNo) throws IOException { BBSData data=readData(category, articleNo); /* String string="["+articleNo+convertToASCII("¹øÂ° ±Û]")+data.title; printTitle(out, string); out.println("

"+string+"

\n"); */ printTitle(out, data.title); out.println("

"+data.title+"

\n"); } /** * getTopArticleNumber() * this method returns thread top article number * @param String category to specify bbs * @param int articleNo article number * @return int thread-top article number */ static int getTopArticleNumber(String category, int articleNo) { BBSData data=null; int result=articleNo; while(true) { try { data=readData(category, result); if (data == null) return result; if (data.prevNo<0) /* if thread-beginning article */ return result; else result=data.prevNo; } catch (IOException ie) { break;} } return result; } /** * printNextPrevList() * this method prints next and prev article's title * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number * @exception java.io.IOException */ static void printNextPrevList(ServletOutputStream out, String category, int articleNo) throws IOException { Vector vector1=null, vector2=null; BBSData data=null; articleNo=getTopArticleNumber(category, articleNo); vector1=readPrevArticle(category, articleNo, 2); // readPrevArticle includes self vector2=readNextArticle(category, articleNo, 2); // readNextArticle includes self int size1=vector1.size(); int size2=vector2.size(); if (size1<=1 && size2<=1) return; out.println(""); if (size1>1) { try { data=(BBSData) vector1.elementAt(1); // 1 is prev out.println(""); out.println(""); out.println(""); out.println(""); if (data.webAddress!=null) { out.print(""); } else if (data.emailAddress!=null) { out.print(""); } else out.println(""); out.println(""); out.print(""); out.println(""); // print successive threads for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNo=((Integer) enum.nextElement()).intValue(); printNextThreadTitle(out, category, nextNo, 0); } } catch (ArrayIndexOutOfBoundsException e) { } } if (size2>1) { try { data=(BBSData) vector2.elementAt(0); // 0 is next out.println(""); out.println(""); out.println(""); out.println(""); if (data.webAddress!=null) { out.print(""); } else if (data.emailAddress!=null) { out.print(""); } else out.println(""); out.println(""); out.print(""); out.println(""); // print successive threads for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNo=((Integer) enum.nextElement()).intValue(); printNextThreadTitle(out, category, nextNo, 0); } } catch (ArrayIndexOutOfBoundsException e) { } } out.println("
"+convertToASCII("¾Õ ±Û")+"
\"*\""+data.articleNo+""); printLink(out, data.name, data.webAddress.toString()); out.println(""); printLink(out, data.name, data.emailAddress.toString()); out.println(""+data.name+""+convertToASCII(formatDateSimple(data.logDate))+""); printLink(out, data.title, printURL+"?cate="+category+"&number="+data.articleNo); out.println("
"+convertToASCII("´ÙÀ½ ±Û")+"
\"*\""+data.articleNo+""); printLink(out, data.name, data.webAddress.toString()); out.println(""); printLink(out, data.name, data.emailAddress.toString()); out.println(""+data.name+""+convertToASCII(formatDateSimple(data.logDate))+""); printLink(out, data.title, printURL+"?cate="+category+"&number="+data.articleNo); out.println("
"); } /** * printArticleFooter() * this method prints article's footer * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number * @exception java.io.IOException */ static void printArticleFooter(ServletOutputStream out, String category, int articleNo) throws IOException { printNextPrevList(out, category, articleNo); out.println(""); out.println(""); out.println(""); out.println(""); out.print(""); out.println("

"); printLink(out, convertToASCII("À̾ ±Û ¾²±â"), postURL+"?cate="+category+"&replyto="+articleNo); out.print(" - "); printLink(out, convertToASCII("¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+(articleNo+9)+"&dir=-1"); out.print(" - "); printLink(out, convertToASCII("»õ±Û ¾²±â"), postURL+"?cate="+category); out.print(" - "); printLink(out, convertToASCII("°íÄ¡±â"), editURL+"?cate="+category+"&number="+articleNo); out.print(" - "); printLink(out, convertToASCII("Áö¿ì±â"), deleteURL+"?cate="+category+"&number="+articleNo); out.println(""); out.println("

"); printLink(out, "\"goto", homeURL+"/"+category); out.println("
"); out.println("\n"); } /** * printListHeader() * this method prints article list's header * @param ServletOutputStream output stream to print * @exception java.io.IOException */ static void printListHeader(ServletOutputStream out) throws IOException { String string=convertToASCII("±â»ç ¸ñ·Ï º¸±â"); printTitle(out, string); out.println("

"+string+"

\n"); } /** * printListFooter() * this method prints article list's footer * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int beginIndex first article number * @param int endIndex last article number * @exception java.io.IOException */ static void printListFooter(ServletOutputStream out, String category, int beginIndex, int endIndex) throws IOException { out.println(""); out.println(""); out.println(""); out.print(""); out.println(""); out.println(""); out.println("

"); printLink(out, convertToASCII("ÀÌÀü ¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+beginIndex+"&dir=-1"); out.print(" - "); printLink(out, convertToASCII("´ÙÀ½ ¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+endIndex+"&dir=1"); out.print(" - "); printLink(out, convertToASCII("»õ±Û ¾²±â"), postURL+"?cate="+category); out.println("

"); printLink(out, "\"goto", homeURL+"/"+category); out.println("

"); printLink(out, convertToASCII("Àüü ȨÆäÀÌÁö·Î À̵¿"), homeURL); out.println("
"); out.println("\n"); } /** * printListFooterSSI() * this method prints article list's footer * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int beginIndex first article number * @param int endIndex last article number * @exception java.io.IOException */ static void printListFooterSSI(ServletOutputStream out, String category, int beginIndex, int endIndex) throws IOException { out.println(""); out.println(""); out.println("

"); printLink(out, convertToASCII("ÀÌÀü ¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+beginIndex+"&dir=-1"); out.print(" - "); printLink(out, convertToASCII("´ÙÀ½ ¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+endIndex+"&dir=1"); out.print(" - "); printLink(out, convertToASCII("»õ±Û ¾²±â"), postURL+"?cate="+category); out.println("
"); } /** * printDeleteHeader() * this method prints header when challenged to delete * @param ServletOutputStream output stream to print * @param articleNo article number to delete * @exception java.io.IOException */ static void printDeleteHeader(ServletOutputStream out, int articleNo) throws IOException { String string=articleNo+convertToASCII("¹ø ±â»ç »èÁ¦"); printTitle(out, string); out.println("

"+string+"

"); } /** * printDeleteFooter() * this method prints footer when challenged to delete * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param articleNo article number to delete * @exception java.io.IOException */ static void printDeleteFooter(ServletOutputStream out, String category, int articleNo) throws IOException { printNextPrevList(out, category, articleNo); out.println(""); out.println(""); out.println(""); out.print(""); out.println("

"); printLink(out, convertToASCII("¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+(articleNo+9)+"&dir=-1"); out.print(" - "); printLink(out, convertToASCII("»õ±Û ¾²±â"), postURL+"?cate="+category); out.println(""); out.println("

"); printLink(out, "\"goto", homeURL+"/"+category); out.println("
"); out.println("\n"); } /** * printEditHeader() * this method prints edit-article header * @param ServletOutputStream output stream to print * @param int articleNo article number * @exception java.io.IOException */ static void printEditHeader(ServletOutputStream out, int articleNo) throws IOException { String string=articleNo+convertToASCII("¹øÂ° ±Û ÆíÁý"); printTitle(out, string); out.println("

"+string+"

\n"); } /** * printEditFooter() * this method prints edit-article footer * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number * @exception java.io.IOException */ static void printEditFooter(ServletOutputStream out, String category, int articleNo) throws IOException { printNextPrevList(out, category, articleNo); out.println(""); out.println(""); out.print(""); out.println("

"); printLink(out, convertToASCII("À̾ ±Û ¾²±â"), postURL+"?cate="+category+"&replyto="+articleNo); out.print(" - "); printLink(out, convertToASCII("¸ñ·Ï º¸±â"), listURL+"?cate="+category+"&start="+(articleNo+9)+"&dir=-1"); out.print(" - "); printLink(out, convertToASCII("»õ±Û ¾²±â"), postURL+"?cate="+category); out.print(" - "); printLink(out, convertToASCII("°íÄ¡±â"), editURL+"?cate="+category+"&number="+articleNo); out.print(" - "); printLink(out, convertToASCII("Áö¿ì±â"), deleteURL+"?cate="+category+"&number="+articleNo); out.println(""); out.println("

"); printLink(out, "\"goto", homeURL+"/"+category); out.println("
"); out.println("\n"); } /** * printAdminEditHeader() * this method prints edit-article header for Administrator * @param ServletOutputStream output stream to print * @param int articleNo article number * @exception java.io.IOException */ static void printAdminEditHeader(ServletOutputStream out, int articleNo) throws IOException { String string=articleNo+convertToASCII("¹øÂ° ±Û ÆíÁý(°ü¸®ÀÚ)"); printTitle(out, string); out.println("

"+string+"

\n"); } /** * printAdminEditFooter() * this method prints edit-article footer for Administrator * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number * @exception java.io.IOException */ static void printAdminEditFooter(ServletOutputStream out, String category, int articleNo) throws IOException { printEditFooter(out, category, articleNo); } /** * printPostHeader() * this method prints header to post an article * @param ServletOutputStream output stream to print * @exception java.io.IOException */ static void printPostHeader(ServletOutputStream out) throws IOException { String string=convertToASCII("°Ô½ÃÆÇ¿¡ ±Û ¾²±â"); printTitle(out, string); out.println("

"+string+"

\n"); } /** * printPostFooter() * this method prints footer to post an article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @exception java.io.IOException */ static void printPostFooter(ServletOutputStream out, String category) throws IOException { out.println(""); out.println(""); out.print(""); out.println("

"); printLink(out, "\"goto", homeURL+"/"+category); out.println("
"); out.println("\n"); } /** * printEditChallenge() * this method prints article in edit form * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData data article content to update * @exception java.io.IOException */ static void printEditChallenge(ServletOutputStream out, String category, BBSData data) throws IOException { if (data==null) { out.println("

Specified article not found!

"); return; } out.println("

"); out.println(""); else out.println(""); out.println(""); out.println(""); if (data.emailAddress!=null) out.println(""); else out.println(""); out.println(""); if (data.webAddress!=null) out.println(""); else out.println(""); out.println(""); if (data.title!=null) out.println(""); else out.println(""); out.println(""); if (data.data!=null) out.println(""); else out.println(""); out.println("
"); out.println(convertToASCII("ÀÌ ¸§")); if (data.name!=null) out.println("
"); out.println(convertToASCII("¾Ï È£")); out.println("
"); out.println("E-Mail "+convertToASCII("ÁÖ¼Ò")+"(Optional)
"+ convertToASCII("ȨÆäÀÌÁö")+" URL(Optional)
"+convertToASCII("Á¦ ¸ñ")+"
"+convertToASCII("²ôÀû²ôÀû")+"
"); out.println(""); out.println(""); out.println(""); out.println("
"); } /** * printEditResult() * this method prints the result of update an article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData newData article content to update * @exception java.io.IOException */ static void printEditResult(ServletOutputStream out, String category, BBSData newData) throws IOException { boolean isUpdated=updateDataWithAuth(category, newData); if (isUpdated) { printArticle(out, category, newData); } else { out.println(""); out.print(convertToASCII("ÆÐ½º¿öµå°¡ ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù.")); out.println("
"); out.println(convertToASCII("±â»ç °»½Å¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); out.println("
"); return; } } /** * printPrevThread() * this method prints prev article in the threads' title * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int prevNo previous article no. in this thread * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printPrevThread(ServletOutputStream out, String category, int prevNo) throws IOException { try { BBSData data=readData(category, prevNo); if ( data!=null && data.nextNumbers!=null && !data.nextNumbers.isEmpty() ) { out.println(""+convertToASCII("¾²·¹µå ¾Õ ±Û")+""); // print article header /* out.println(""); out.println(""); out.println(""+convertToASCII("¹ø È£")+""); out.println(""+convertToASCII("±Û¾´ÀÌ")+""); out.println(""+convertToASCII("±Û¾´ ³¯Â¥")+""); out.println(""+convertToASCII("Á¦ ¸ñ")+""); out.println(""); */ out.println(""); out.println("\"*\""); out.println(""+data.articleNo+""); if (data.webAddress!=null) { out.print(""); printLink(out, data.name, data.webAddress.toString()); out.println(""); } else if (data.emailAddress!=null) { out.print(""); printLink(out, data.name, data.emailAddress.toString()); out.println(""); } else out.println(""+data.name+""); out.println(""+convertToASCII(formatDateSimple(data.logDate))+""); out.print(""); printLink(out, data.title, printURL+"?cate="+category+"&number="+data.articleNo); out.println(""); out.println(""); } } catch (IOException ie) {} } // end of printPrevThread() /** * printNextThreadTitle() * this method prints next article thread's title * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param nextNo number of next article * @param indentBase number of next article * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printNextThreadTitle(ServletOutputStream out, String category, int nextNo, int indentBase) throws IOException { try { BBSData data=readData(category, nextNo); if (data==null) return; out.println(""); out.print(""); for (int i=0; i\"*\""); out.println(""+data.articleNo+""); if (data.webAddress!=null) { out.print(""); printLink(out, data.name, data.webAddress.toString()); out.println(""); } else if (data.emailAddress!=null) { out.print(""); printLink(out, data.name, data.emailAddress.toString()); out.println(""); } else out.println(""+data.name+""); out.println(""+convertToASCII(formatDateSimple(data.logDate))+""); out.print(""); printLink(out, data.title, printURL+"?cate="+category+"&number="+data.articleNo); out.println(""); out.println(""); for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNextNo=((Integer) enum.nextElement()).intValue(); printNextThreadTitle(out, category, nextNextNo, indentBase+1); // recursive call } } catch (IOException ie) {} } /** * printNextThreads() * this method prints article threads' titles * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData data file to print * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printNextThreads(ServletOutputStream out, String category, BBSData data) throws IOException { /* if child data exist ... */ if (data.nextNumbers !=null && !data.nextNumbers.isEmpty()) { out.println(""+convertToASCII("¾²·¹µå ´ÙÀ½ ±Û")+""); /* // print article header out.println(""); out.println(""); out.println(""+convertToASCII("¹ø È£")+""); out.println(""+convertToASCII("±Û¾´ÀÌ")+""); out.println(""+convertToASCII("±Û¾´ ³¯Â¥")+""); out.println(""+convertToASCII("Á¦ ¸ñ")+""); out.println(""); */ for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNo=((Integer) enum.nextElement()).intValue(); printNextThreadTitle(out, category, nextNo, 0); } } } // end of printNextThreads() /** * printArticle() * this method prints formatted article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData data file to print * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printArticle(ServletOutputStream out, String category, BBSData data) throws IOException { int count=getCount(category); // print table header out.println(""); out.println(""); out.println(""); out.println("
"+count+convertToASCII("°³ ±Û Áß ")+data.articleNo+convertToASCII("¹øÂ° ±Û")+"
"); out.println(""); out.println(""); if (data.webAddress!=null) { out.print(""); } else { out.println(""); } out.println(""); if (data.emailAddress!=null) { out.println(""); out.println(""); out.print(""); out.println(""); } out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println("
"+convertToASCII("ÀÌ ¸§")+""); printLink(out, data.name, data.webAddress.toString()); out.println(""+data.name+"
E-MAIL"); printLink(out, data.emailAddress.toString(), data.emailAddress.toString()); out.println("
" +convertToASCII("±Û¾´ ³¯Â¥")+"" +convertToASCII(formatDateInKorean(data.logDate))+"
" +convertToASCII("Á¦ ¸ñ")+"" +data.title+"
"); out.println(""); out.println(""); out.println(""); out.println(""); out.println("
"); int beginIndex=0; int endIndex=0; while ((endIndex=data.data.indexOf('\n', beginIndex))>=0) { out.println(data.data.substring(beginIndex, endIndex)); out.println("
"); beginIndex=endIndex+1; } try { out.println(data.data.substring(beginIndex)); } catch (StringIndexOutOfBoundsException e) { } out.println("
"); out.println("

"); out.println(""); /* if parent data exist ... */ if (data.prevNo>0) printPrevThread(out, category, data.prevNo); /* if child data exist ... */ printNextThreads(out, category, data); out.println("
"); } // end of printArticle() /** * printArticleList() * this method prints formatted article's header * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param count specify from which file (nth article) to read * @param nItems specify number of file to read * @param isNext specify order * @exception java.io.IOException */ static int[] printArticleList(ServletOutputStream out, String category, int count, int nItems, boolean isNext) throws IOException { BBSData data=null; Vector vector=null; int beginIndex=0, endIndex=0; int totalCount=getCount(category); if (count<=0) { count=totalCount; isNext=false; } if (isNext) vector=readNextArticle(category, count, nItems); else vector=readPrevArticle(category, count, nItems); // print html header // printListHeader(out); // print table header out.println(""); out.println(""); out.println(""); out.println("
"+convertToASCII("Àüü ")+totalCount+convertToASCII("°³ ±Û")+"
"); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); int size=vector.size(); try { for (int i=0; i"); out.println(""); out.println(""); if (data.webAddress!=null) { out.print(""); } else if (data.emailAddress!=null) { out.print(""); } else out.println(""); out.println(""); out.print(""); out.println(""); // print successive threads for (Enumeration enum = data.nextNumbers.elements(); enum.hasMoreElements(); ) { int nextNo=((Integer) enum.nextElement()).intValue(); printNextThreadTitle(out, category, nextNo, 0); } } beginIndex=((BBSData) vector.elementAt(size-1)).articleNo; endIndex=((BBSData) vector.elementAt(0)).articleNo; } catch (ArrayIndexOutOfBoundsException e) { } out.println("
"+convertToASCII("¹ø È£")+""+convertToASCII("±Û¾´ÀÌ")+""+convertToASCII("±Û¾´ ³¯Â¥")+""+convertToASCII("Á¦ ¸ñ")+"
\"*\""+data.articleNo+""); printLink(out, data.name, data.webAddress.toString()); out.println(""); printLink(out, data.name, data.emailAddress.toString()); out.println(""+data.name+""+convertToASCII(formatDateSimple(data.logDate))+""); printLink(out, data.title, printURL+"?cate="+category+"&number="+data.articleNo); out.println("
"); // print html footer // printListFooter(out, category, beginIndex, endIndex); int index[]=new int[2]; index[0]=beginIndex; index[1]=endIndex; return index; } // end of printArticleList() /** * printDeleteChallenge() * this method challenges to delete an article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param articleNo article number to delete * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printDeleteChallenge(ServletOutputStream out, String category, int articleNo) throws IOException { out.println("

"); out.println("
"); out.println(""); out.println(""); out.println("
"); out.println(convertToASCII("¾Ï È£")); out.println(""); out.println("
"); out.println(""); out.println(""); out.println("
"); } // end of printDeleteChallenge() /** * printDeleteResult() * this method prints the result of deleting an article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param int articleNo article number to delete * @param String password for authentication * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printDeleteResult(ServletOutputStream out, String category, int articleNo, String password) throws IOException { if (articleNo<0) { // delete operation needs to know accurate article number out.println(""); out.println(convertToASCII("À߸øµÈ ±â»ç ¹øÈ£ÀÔ´Ï´Ù.")); out.println(""); out.println(""); out.println("

"); return; } BBSData oldData=new BBSData(); oldData=readData(category, articleNo); out.println(""); if (password.equals(oldData.passwd) || password.equals(masterKey)) { boolean isDeleted=removeData(category, articleNo); if (isDeleted) out.println(articleNo+convertToASCII("¹øÂ° ±â»ç°¡ »èÁ¦µÇ¾ú½À´Ï´Ù.")); else out.println(articleNo+convertToASCII("¹øÂ° ±â»ç »èÁ¦¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); } else { out.println(convertToASCII("ÆÐ½º¿öµå°¡ ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù.")); // out.println("DEBUG:old="+oldData.passwd+" new="+password); } out.println(""); out.println(""); out.println("

"); printArticleList(out, category, articleNo, 10, false); } // end of printDeleteResult() /** * printPostChallenge() * this method challenges to post an article * @param ServletOutputStream output stream to print * @param String category to specify bbs * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printPostChallenge(ServletOutputStream out, String category, int replyTo) throws IOException { boolean isReply=false; BBSData data=null; if (replyTo > 0) { try { data=readData(category, replyTo); if (data !=null) isReply=true; } catch (IOException ie) { } } out.println(""); out.print("
"); if (isReply) out.print(convertToASCII("À̾ ±Û ¾²±â")); else out.print(convertToASCII("°Ô½ÃÆÇ¿¡ ±Û ¾²±â")); out.print("
\n
"); out.print(convertToASCII("Let's ²ôÀû²ôÀû...")); out.print("
\n
\n
\n"); out.println("
"); out.print("\n\n"); out.println(""); out.print("\n\n\n"); out.print("\n\n\n\n\n\n"); out.print("\n\n\n"); out.print("\n\n\n\n\n"); } else out.println("\n\n\n"); out.print("\n"); out.println("\n\n"); out.print("\n\n
"); out.print(convertToASCII("ÀÌ ¸§")); out.println("
"); out.print(convertToASCII("¾Ï È£")); out.println("
"); out.print(convertToASCII("E-Mail ÁÖ¼Ò(Optional)")); out.println("
"); out.print(convertToASCII("ȨÆäÀÌÁö URL(Optional)")); out.println("
"); out.print(convertToASCII("Á¦ ¸ñ")); if (isReply) { out.print("
"); out.print(convertToASCII("²ôÀû²ôÀû")); out.println("
"); out.print(" 
"); out.println(""); if (isReply) // considered when data is null out.println(""); out.println("
"); } // end of printPostChallenge() /** * printAdminEditPage() * this method prints a page for admin to edit article manually * @param ServletOutputStream output stream to print * @see yoonforh.bbs.BBSData * @exception java.io.IOException */ static void printAdminEditPage(ServletOutputStream out) throws IOException { String title=convertToASCII("±â»ç ÆíÁý(°ü¸®ÀÚ)"); printTitle(out, title); out.println("

"+title+"

"); out.println("

"); out.println("
"); out.println(""); out.println(""); out.print(""); out.println(""); out.println(""); out.println(""); out.print(""); out.println(""); out.println(""); out.println(""); out.print(""); out.println(""); out.println(""); out.print(""); out.println("
"); out.print(convertToASCII("¹üÁÖ")); out.println("
"); out.print(convertToASCII("±â»ç ¹øÈ£")); out.println("
"); out.print(convertToASCII("°ü¸®ÀÚ ¾ÏÈ£")); out.println("
"); out.println("
"); out.println(""); out.println(""); out.println("

"); printLink(out, convertToASCII("Àüü ȨÆäÀÌÁö·Î À̵¿"), homeURL); out.println("
"); out.println("\n"); } // end of printAdminEditPage() /** * printAdminEditChallenge() * this method prints article in edit form for administrator * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData data article content to update * @exception java.io.IOException */ static void printAdminEditChallenge(ServletOutputStream out, String category, BBSData data) throws IOException { if (data==null) { out.println("

Specified article not found!

"); return; } out.println("

"); out.println(""); else out.println(""); out.println(""); // show password to adminer out.println(""); if (data.emailAddress!=null) out.println(""); else out.println(""); out.println(""); if (data.webAddress!=null) out.println(""); else out.println(""); out.println(""); if (data.title!=null) out.println(""); else out.println(""); out.println(""); if (data.data!=null) out.println(""); else out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println("
"); out.println(convertToASCII("ÀÌ ¸§")); if (data.name!=null) out.println("
"); out.println(convertToASCII("¾Ï È£")); out.println("
"); out.println("E-Mail "+convertToASCII("ÁÖ¼Ò")+"(Optional)
"+ convertToASCII("ȨÆäÀÌÁö")+" URL(Optional)
"+convertToASCII("Á¦ ¸ñ")+"
"+convertToASCII("²ôÀû²ôÀû")+"
"); out.println(convertToASCII("¾Õ ±Û(thread)")); out.println("
"); out.println(convertToASCII("´ÙÀ½ ±Ûµé(thread)")); out.print("
"); out.println("
"); } /** * printAdminEditResult() * this method prints the result of update an article for administrator * @param ServletOutputStream output stream to print * @param String category to specify bbs * @param BBSData newData article content to update * @exception java.io.IOException */ static void printAdminEditResult(ServletOutputStream out, String category, BBSData newData) throws IOException { boolean isUpdated=updateDataWithAuth(category, newData); if (isUpdated) { printArticle(out, category, newData); } else { out.println(""); out.print(convertToASCII("ÆÐ½º¿öµå°¡ ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù.")); out.println("
"); out.println(convertToASCII("±â»ç °»½Å¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.")); out.println("
"); return; } } /** * makeLink() * this method add link to specified string * @param string string to make link * @param URLString indicates link * @return String string with URL anchor */ private static String makeLink(String string, String URLString) { return (""+string+""); } // end of makeLink() /** * printLink() * this method add link to specified string * @param ServletOutputStream out stream to print * @param string string to make link * @param URLString indicates link * @exception java.io.IOException */ private static void printLink(ServletOutputStream out, String string, String URLString) throws IOException { out.print(""); out.print(string); out.print(""); } // end of printLink() /** * formatDateSimple() * this method prints formatted article * @param Date date to format * @return String formatted date */ private static String formatDateSimple(Date date) { final int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new SimpleDateFormat(); fmt=(SimpleDateFormat) DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, Locale.KOREAN); SimpleTimeZone timeZone = new SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone); return fmt.format(date); } // end of formatDateSimple() /** * formatDateInKorean() * this method prints formatted article * @param Date date to format * @return String formatted date */ private static String formatDateInKorean(Date date) { final int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new SimpleDateFormat(); fmt=(SimpleDateFormat) DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale.KOREAN); SimpleTimeZone timeZone = new SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone); return fmt.format(date); } // end of formatDateInKorean() /** * convertToCp949() * this method converts ISO8859_1 encoded character to Cp949 encoded * @param String string to converted * @return String converted string */ private static String convertToCp949(String str) { String result=null; try { byte[] rawBytes=str.getBytes("8859_1"); result=new String(rawBytes, "Cp949"); } catch (java.io.UnsupportedEncodingException e) { System.err.println(e.toString()); } return result; } /** * convertToASCII() * this method converts Cp949 encoded character to ISO8859_1 encoded * @param String string to converted * @return String converted string */ private static String convertToASCII(String str) { try { byte[] kscBytes=str.getBytes("Cp949"); str=new String(kscBytes, "8859_1"); } catch (java.io.UnsupportedEncodingException e) { System.err.println(e.toString()); } return str; } } // end of class BBSUtil