From b12dfac6e495d6cf38df6b7e5222191f59762900 Mon Sep 17 00:00:00 2001 From: IT-KIMI_SHI\SINOIT.KIMI <kimi42345@gmail.com> Date: 星期一, 04 六月 2018 19:05:10 +0800 Subject: [PATCH] no message --- source/my/.metadata/.plugins/org.eclipse.core.resources/.history/57/a05071b0c36700181c5ca0c66caaee5f | 181 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/c09a5901876500181663a2994eb26aa3 | 52 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1e.cfs | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/d00ab2d8866500181663a2994eb26aa3 | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/d06b1ea1e46700181c5ca0c66caaee5f | 80 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/d06df1abc36700181c5ca0c66caaee5f | 180 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/406b9ceb866500181663a2994eb26aa3 | 53 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1/b0bdb9e8866500181663a2994eb26aa3 | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/d06a9304bd6700181c5ca0c66caaee5f | 91 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/e04a80f1866500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/45/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/803adefe866500181663a2994eb26aa3 | 84 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/9d/history.index | 0 source/my/frame/WebRoot/lib/portlet.jar | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/3085b8e8866500181663a2994eb26aa3 | 78 source/my/frame/.classpath | 3 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/62/d021e071856500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/85/3023b499876500181663a2994eb26aa3 | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/9d/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6f/f087d5fe866500181663a2994eb26aa3 | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2/1068e697876500181663a2994eb26aa3 | 329 source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs | 2 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/103ec325a46700181c5ca0c66caaee5f | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/f0bc5201876500181663a2994eb26aa3 | 102 source/my/frame/src/frame/file/repositoty/RepositoryContainer.java | 91 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/20767ef1866500181663a2994eb26aa3 | 84 source/my/.metadata/.plugins/org.eclipse.wst.jsdt.core/indexes/savedIndexNames.txt | 8 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5d/00cf9beb866500181663a2994eb26aa3 | 50 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/50895801876500181663a2994eb26aa3 | 111 source/my/frame/src/frame/upload/servlet/ServletFileUpload.java | 46 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/509571b3e46700181c5ca0c66caaee5f | 26 source/my/.metadata/.plugins/org.eclipse.core.resources/.snap | 0 source/my/frame/src/frame/upload/util/FileItemHeadersImpl.java | 90 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0d7d697876500181663a2994eb26aa3 | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d7/d09482f1866500181663a2994eb26aa3 | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/c011b399876500181663a2994eb26aa3 | 53 source/my/frame/src/frame/upload/MultipartStream.java | 1010 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/20c1dffe866500181663a2994eb26aa3 | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/16/60ebbb99876500181663a2994eb26aa3 | 51 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d_1.del | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50185601876500181663a2994eb26aa3 | 50 source/my/.metadata/.plugins/org.eclipse.jdt.core/436671472.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/45/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5e/b0feb79eda6700181c5ca0c66caaee5f | 548 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/39/a0f0cb25a46700181c5ca0c66caaee5f | 109 source/my/frame/WebRoot/lib/jacob.jar | 0 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t.cfs | 0 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments.gen | 0 source/my/frame/WebRoot/lib/commons-io-2.4.jar | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/15/0057b13e876500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/c085f745876500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.tigris.subversion.subclipse.ui/dialog_settings.xml | 18 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/dd/6027b299876500181663a2994eb26aa3 | 77 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fd/f0c68253876500181663a2994eb26aa3 | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/10679eeb866500181663a2994eb26aa3 | 675 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/0002ddfe866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b083215b8c6500181663a2994eb26aa3 | 88 source/my/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5035be99876500181663a2994eb26aa3 | 52 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b035c725a46700181c5ca0c66caaee5f | 102 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/75/history.index | 0 source/my/frame/src/frame/upload/FileItemFactory.java | 52 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8c/902e9deb866500181663a2994eb26aa3 | 64 source/my/.metadata/.plugins/org.eclipse.jdt.core/3774752620.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/80b8b3d8866500181663a2994eb26aa3 | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/a0f9e0fe866500181663a2994eb26aa3 | 64 source/my/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml | 162 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/00c7aba6e46700181c5ca0c66caaee5f | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/56/0090b899876500181663a2994eb26aa3 | 329 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/60bae497876500181663a2994eb26aa3 | 1010 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0d1c725a46700181c5ca0c66caaee5f | 109 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/1033da97876500181663a2994eb26aa3 | 51 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/00f9b470da6700181c5ca0c66caaee5f | 189 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50eb7ef1866500181663a2994eb26aa3 | 46 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/309fd597876500181663a2994eb26aa3 | 111 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/4024c625a46700181c5ca0c66caaee5f | 51 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/92/60045771e56700181c5ca0c66caaee5f | 239 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fa/d0ca9deb866500181663a2994eb26aa3 | 99 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8f/f03ab7d8866500181663a2994eb26aa3 | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a6/1099bd99876500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.history | 3 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments.gen | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/408db5d8866500181663a2994eb26aa3 | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/88/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/13/90e7f8a3da6700181c5ca0c66caaee5f | 569 source/my/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/50/701ddb97876500181663a2994eb26aa3 | 53 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/87/6041b23e876500181663a2994eb26aa3 | 46 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers.snap | 0 source/my/frame/src/frame/upload/FileUpload.java | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5c/8057b799876500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6b/30e18d0bd66700181c5ca0c66caaee5f | 70 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_t | 0 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/a0273121876500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/508b8c05d26700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c4/d007dc97876500181663a2994eb26aa3 | 102 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7052e797876500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/2/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/80dec125a46700181c5ca0c66caaee5f | 111 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/e0b8301e876500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/50237afebc6700181c5ca0c66caaee5f | 91 source/my/frame/src/frame/file/office/Engine.java | 2 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/e062a0eb866500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.syncinfo.snap | 0 source/my/frame/src/frame/upload/InvalidFileNameException.java | 50 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/6086bc67da6700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cf/e039378c876500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d.cfs | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/4077cd25a46700181c5ca0c66caaee5f | 46 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/df/30537ac6e46700181c5ca0c66caaee5f | 79 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40805301876500181663a2994eb26aa3 | 51 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cb/70acd897876500181663a2994eb26aa3 | 52 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6/00097dace46700181c5ca0c66caaee5f | 31 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/90e0bbe8866500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/36/202a19f2e46700181c5ca0c66caaee5f | 87 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/47/d065cc25a46700181c5ca0c66caaee5f | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/45/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b2/4082b8f3e46700181c5ca0c66caaee5f | 88 source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs | 2 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/90d0f02c876500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/c0c378febc6700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/74/30374c8e876500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_u.cfs | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/80fe5801876500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1c/400b9204bd6700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/a0b33d29876500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/d08bba99876500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/27/50dac325a46700181c5ca0c66caaee5f | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/9d/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/80b9b213bd6700181c5ca0c66caaee5f | 91 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/005fe197876500181663a2994eb26aa3 | 99 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/90842d1e876500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5043b3d8866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/f06e2e1e876500181663a2994eb26aa3 | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/608381f1866500181663a2994eb26aa3 | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c08dd497876500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/90f881f1866500181663a2994eb26aa3 | 109 source/my/frame/src/frame/upload/portlet/PortletFileUpload.java | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/804a3321876500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/1098ef2c876500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4c/70a1b999876500181663a2994eb26aa3 | 102 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10afc525a46700181c5ca0c66caaee5f | 52 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/70a72f1e876500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/78/306ec825a46700181c5ca0c66caaee5f | 675 + source/my/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/80/40a1a362c16700181c5ca0c66caaee5f | 178 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/de/e0233b58c16700181c5ca0c66caaee5f | 188 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/58/602a9feb866500181663a2994eb26aa3 | 329 source/my/.metadata/.plugins/org.eclipse.wst.validation/dep.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/53/e0343421876500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/8029b6d8866500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8d/c0d5bc99876500181663a2994eb26aa3 | 50 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/98/30d71868da6700181c5ca0c66caaee5f | 188 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/88/history.index | 0 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1c | 0 source/my/frame/src/frame/upload/FileItem.java | 229 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/30d0ac99876500181663a2994eb26aa3 | 675 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/403581f1866500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/204fbb99876500181663a2994eb26aa3 | 64 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/d0fddefe866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/13.png | 0 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1q | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/be/00dbcc25a46700181c5ca0c66caaee5f | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e039c525a46700181c5ca0c66caaee5f | 229 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/af/a0c69feb866500181663a2994eb26aa3 | 111 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/700e8875e66700181c5ca0c66caaee5f | 238 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/83/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/e032bae8866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b5/5054dbfe866500181663a2994eb26aa3 | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/6/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/42/3003ebb2c36700181c5ca0c66caaee5f | 182 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers | 0 source/my/frame/src/frame/file/ActivePeriod.java | 88 source/my/frame/src/frame/upload/util/Streams.java | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09a98eb866500181663a2994eb26aa3 | 77 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/6/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d052b33e876500181663a2994eb26aa3 | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/30f28053876500181663a2994eb26aa3 | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/f0e74029876500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/10393221876500181663a2994eb26aa3 | 38 source/my/frame/src/frame/upload/FileItemHeadersSupport.java | 51 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2b/d00bbae8866500181663a2994eb26aa3 | 46 source/my/frame/src/frame/upload/DefaultFileItemFactory.java | 111 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0a6c925a46700181c5ca0c66caaee5f | 144 source/my/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml | 74 source/my/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap | 0 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments.gen | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c6/c00c56b5e46700181c5ca0c66caaee5f | 30 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png | 0 source/my/frame/src/frame/upload/FileItemStream.java | 102 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b0ff039ed46700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/e0a2b4d8866500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/44/history.index | 0 source/my/frame/src/frame/upload/servlet/FileCleanerCleanup.java | 84 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/65/b05ea2eb866500181663a2994eb26aa3 | 229 source/my/frame/src/frame/upload/ProgressListener.java | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/80bf4e598c6500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/407c00bcda6700181c5ca0c66caaee5f | 125 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7e/70eccd25a46700181c5ca0c66caaee5f | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d2/3090705cc16700181c5ca0c66caaee5f | 188 source/my/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml | 6 source/my/frame/src/frame/upload/RequestContext.java | 64 source/my/frame/src/frame/upload/util/Closeable.java | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e0203e7ee66700181c5ca0c66caaee5f | 239 source/my/frame/src/frame/file/office/excel/ExcelTranslator.java | 240 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f4/9021f648bd6700181c5ca0c66caaee5f | 88 source/my/frame/src/frame/upload/disk/DiskFileItemFactory.java | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cc/5001bfb8e46700181c5ca0c66caaee5f | 31 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7/b00a4e5cda6700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b0/103183f1866500181663a2994eb26aa3 | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/1046b699876500181663a2994eb26aa3 | 229 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/90eeeb2c876500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml | 2 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4/b02db4d8866500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5b/20617b72da6700181c5ca0c66caaee5f | 189 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6c/5072d6fe866500181663a2994eb26aa3 | 89 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/10c080f1866500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/c0329beb866500181663a2994eb26aa3 | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/009e3e29876500181663a2994eb26aa3 | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8e/f02d5501876500181663a2994eb26aa3 | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/63/d03ce897876500181663a2994eb26aa3 | 64 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/f0faa2eb866500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/70ddaf99876500181663a2994eb26aa3 | 1010 + source/my/.metadata/.plugins/org.eclipse.jdt.core/1019917792.index | 0 source/my/frame/src/frame/file/office/IOMappingItem.java | 2 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b09eb6d8866500181663a2994eb26aa3 | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b8/50b1df97876500181663a2994eb26aa3 | 675 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f00f5a01876500181663a2994eb26aa3 | 229 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e6/30f2dc97876500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0ae7ff1866500181663a2994eb26aa3 | 38 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1e/f03699eb866500181663a2994eb26aa3 | 102 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2f/c06fd997876500181663a2994eb26aa3 | 77 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/49/20712d60c16700181c5ca0c66caaee5f | 178 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/404df645876500181663a2994eb26aa3 | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/2/history.index | 0 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png | 0 source/my/frame/src/frame/upload/FileItemIterator.java | 53 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/900db599876500181663a2994eb26aa3 | 111 source/my/frame/src/frame/upload/util/LimitedInputStream.java | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/30ecaa4cbd6700181c5ca0c66caaee5f | 187 source/my/frame/src/frame/upload/disk/DiskFileItem.java | 336 source/my/frame/src/frame/upload/servlet/ServletRequestContext.java | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9d/10ed5701876500181663a2994eb26aa3 | 675 + source/my/frame/src/frame/upload/ParameterParser.java | 329 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/86/908fed93876500181663a2994eb26aa3 | 75 source/my/.metadata/.plugins/org.eclipse.jdt.core/3109331711.index | 0 source/my/frame/src/frame/util/Util.java | 19 source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.history | 2 source/my/.metadata/.plugins/org.eclipse.core.resources/.root/179.tree | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7084e0fe866500181663a2994eb26aa3 | 76 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/68/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/0/20e9d797876500181663a2994eb26aa3 | 229 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/c0d24559e56700181c5ca0c66caaee5f | 239 source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.index | 10 source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.index | 2 source/my/frame/src/frame/upload/FileItemHeaders.java | 77 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/70c2a1eb866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/a0a6d9fe866500181663a2994eb26aa3 | 329 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/89/205eb8e8866500181663a2994eb26aa3 | 336 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5/700ac925a46700181c5ca0c66caaee5f | 1010 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/5022e297876500181663a2994eb26aa3 | 50 source/my/frame/src/frame/upload/DefaultFileItem.java | 76 source/my/frame/src/frame/upload/DiskFileUpload.java | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/606bbbe8866500181663a2994eb26aa3 | 144 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c1/9076c425a46700181c5ca0c66caaee5f | 217 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1f/30d399eb866500181663a2994eb26aa3 | 51 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/80607ff1866500181663a2994eb26aa3 | 36 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/b07bcc0cd66700181c5ca0c66caaee5f | 70 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/20ceb2d8866500181663a2994eb26aa3 | 46 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/d0789fa7c36700181c5ca0c66caaee5f | 179 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/80bdf20bd66700181c5ca0c66caaee5f | 70 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/1018b5d8866500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/50365101876500181663a2994eb26aa3 | 77 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/706f9aeb866500181663a2994eb26aa3 | 1010 + source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1s_1.del | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/80c0c625a46700181c5ca0c66caaee5f | 53 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/aa/e0d1d7fe866500181663a2994eb26aa3 | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/26/3026a1eb866500181663a2994eb26aa3 | 52 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fe/400fe0fe866500181663a2994eb26aa3 | 109 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/79/a088defe866500181663a2994eb26aa3 | 46 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/2/history.index | 0 source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/70a2dbfe866500181663a2994eb26aa3 | 78 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003db199876500181663a2994eb26aa3 | 99 source/my/frame/src/frame/upload/FileUploadException.java | 99 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ca/a035d7fe866500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/48/e075bb25a46700181c5ca0c66caaee5f | 76 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1u.cfs | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/35/c00a6a1fcd6700181c5ca0c66caaee5f | 186 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/b088ce25a46700181c5ca0c66caaee5f | 157 source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.jsp.core.prefs | 4 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/c0fde99fd46700181c5ca0c66caaee5f | 187 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/8038ee2c876500181663a2994eb26aa3 | 38 source/my/frame/src/frame/upload/FileUploadBase.java | 675 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f0/e0775701876500181663a2994eb26aa3 | 99 source/my/frame/src/frame/upload/portlet/PortletRequestContext.java | 109 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t_1.del | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/603ed8cfe46700181c5ca0c66caaee5f | 80 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a06a5401876500181663a2994eb26aa3 | 1010 + source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/004ccf25a46700181c5ca0c66caaee5f | 198 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ae/a0db5601876500181663a2994eb26aa3 | 53 source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1c_1.del | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e1/70af3f29876500181663a2994eb26aa3 | 157 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/history.index | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b02a3608d66700181c5ca0c66caaee5f | 70 /dev/null | 0 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/70770d9de46700181c5ca0c66caaee5f | 80 source/my/frame/src/frame/file/repositoty/Repository.java | 190 source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/history.index | 0 source/my/frame/src/frame/file/ActivePeriodLoader.java | 31 source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/0097b803c46700181c5ca0c66caaee5f | 184 324 files changed, 38,286 insertions(+), 151 deletions(-) diff --git a/source/my/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml b/source/my/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml index 30addf3..197e43c 100644 --- a/source/my/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml +++ b/source/my/.metadata/.plugins/com.genuitec.eclipse.sqlexplorer/SQLDrivers.xml @@ -240,16 +240,6 @@ <url>jdbc:oracle:oci8:@<database_name></url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> - <driverClassName>uk.co.thinksql.ThinkSQLDriver</driverClassName> - <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> - <string>-14</string> - </identifier> - <jarFileName/> - <jarFileNames Indexed="true"/> - <name>ThinkSQL</name> - <url>jdbc:thinksql://<server>:<9075></url> - </Bean> - <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> <driverClassName>sun.jdbc.odbc.JdbcOdbcDriver</driverClassName> <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> <string>-1</string> @@ -260,14 +250,14 @@ <url>jdbc:odbc:<alias></url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> - <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName> + <driverClassName>uk.co.thinksql.ThinkSQLDriver</driverClassName> <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> - <string>-4</string> + <string>-14</string> </identifier> <jarFileName/> <jarFileNames Indexed="true"/> - <name>Oracle (Thin driver)</name> - <url>jdbc:oracle:thin:@<server>[:<1521>]:<database_name></url> + <name>ThinkSQL</name> + <url>jdbc:thinksql://<server>:<9075></url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> <driverClassName>org.hsqldb.jdbcDriver</driverClassName> @@ -280,14 +270,14 @@ <url>jdbc:hsqldb:http://<server>[:<1476>]</url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> - <driverClassName>interbase.interclient.Driver</driverClassName> + <driverClassName>oracle.jdbc.driver.OracleDriver</driverClassName> <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> - <string>-3</string> + <string>-4</string> </identifier> <jarFileName/> <jarFileNames Indexed="true"/> - <name>InterClient</name> - <url>jdbc:interbase://<server>/<full_db_path></url> + <name>Oracle (Thin driver)</name> + <url>jdbc:oracle:thin:@<server>[:<1521>]:<database_name></url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> <driverClassName>com.internetcds.jdbc.tds.Driver</driverClassName> @@ -300,6 +290,16 @@ <url>jdbc:freetds:sqlserver://<hostname>[:<4100>]/<dbname>[;<property>=<value>[;...]]</url> </Bean> <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> + <driverClassName>interbase.interclient.Driver</driverClassName> + <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> + <string>-3</string> + </identifier> + <jarFileName/> + <jarFileNames Indexed="true"/> + <name>InterClient</name> + <url>jdbc:interbase://<server>/<full_db_path></url> + </Bean> + <Bean Class="net.sourceforge.squirrel_sql.fw.sql.SQLDriver"> <driverClassName>org.enhydra.instantdb.jdbc.idbDriver</driverClassName> <identifier Class="net.sourceforge.squirrel_sql.fw.id.UidIdentifier"> <string>-5</string> diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/0/20e9d797876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/0/20e9d797876500181663a2994eb26aa3 new file mode 100644 index 0000000..fe02b63 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/0/20e9d797876500181663a2994eb26aa3 @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.FileUpload FileUpload} instance (see + * {@link foundation.fileupload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1/b0bdb9e8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1/b0bdb9e8866500181663a2994eb26aa3 new file mode 100644 index 0000000..e3abb10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1/b0bdb9e8866500181663a2994eb26aa3 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/13/90e7f8a3da6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/13/90e7f8a3da6700181c5ca0c66caaee5f new file mode 100644 index 0000000..9c8e020 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/13/90e7f8a3da6700181c5ca0c66caaee5f @@ -0,0 +1,569 @@ +package frame.util; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import frame.config.Configer; +import frame.data.DataBaseType; + +public class Util { + + public static final String TRUE = "T"; + public static final String FALSE = "F"; + public static final String String_Return = "\r\n"; + public static final String String_Empty = ""; + + public static String newShortGUID() { + UUID uuid = UUID.randomUUID(); + String strGUID; + String shortGUID; + + strGUID = uuid.toString(); + shortGUID = strGUID.substring(0, 8) + strGUID.substring(9, 13) + strGUID.substring(14, 18) + strGUID.substring(19, 23) + + strGUID.substring(24, 36); + + return shortGUID; + } + + public static String quotedStr(String str) { + if (str != null) + return "'" + str + "'"; + else + return "''"; + } + + public static String doubleQuotedStr(String str) { + if (str != null) + return "\"" + str + "\""; + else + return "\"\""; + } + + public static String quotedLikeStr(String str) { + if (str != null) + return "'%" + str + "%'"; + else + return "''"; + } + + public static String[] split(String str) { + if (str == null) { + return new String[0]; + } + + return str.replace(",", ";").replace("锛�", ";").replace("锛�", ";").split(";"); + } + + public static String newDBDateString() throws Exception { + Date date = new Date(); + return newDBDateString(date); + } + + public static String newDBDateString(Date date) throws Exception { + DataBaseType dbType = Configer.getDataBaseType(); + + if (DataBaseType.Oracle == dbType) { + return newOracleDateString(date); + } + else if (DataBaseType.SQLServer == dbType) { + return newSqlServerDateString(date); + } + else if (DataBaseType.MySQL == dbType) { + return newMySqlDateString(date); + } + else { + return DataTimeToString(date); + } + } + + public static String toOracleDataStr(String dataStr) { + return "to_date('" + dataStr + "','YYYY-MM-DD HH24:MI:SS')"; + } + + public static String toMySQLDateStr(Date value) { + return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss"); + } + + public static String DataTimeToString(Date value) { + return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss"); + } + + public static String DataTimeToString(Date value, String format) { + if (value == null) { + return null; + } + + String result = ""; + DateFormat dateFormat = new SimpleDateFormat(format); + result = dateFormat.format(value); + + return result; + } + + public static String newDateStr() { + return newDateTimeStr("yyyy-MM-dd"); + } + + public static String newDateTimeStr() { + return newDateTimeStr("yyyy-MM-dd kk:mm:ss"); + } + + public static String newDateTimeStr(String fomater) { + return getDateTimeStr(new Date(), fomater); + } + + public static String getDateTimeStr(Date date, String fomater) { + String result = ""; + DateFormat dateFormat = new SimpleDateFormat(fomater); + result = dateFormat.format(date); + + return result; + } + + public static String booleanToStr(boolean value) { + if (value) + return "T"; + else + return "F"; + } + + public static boolean isEmptyStr(Object str) { + boolean result = false; + + if ((str == null) || ("".equals(str))) + result = true; + + return result; + } + + public static String IfEmpetyStr(String str, String value) { + if (isEmptyStr(str)) { + return value; + } + + return str; + } + + public static boolean isNull(String value) { + if ((value == null)) + return true; + + if ("".equals(value)) { + return true; + } + + if (value.length() == 4) { + value = value.toLowerCase(); + return "null".equals(value); + } + + return false; + } + + public static String UTF8decode(String str) { + if (!isUTF8Encoding(str)) + return str; + byte[] bytes = str.getBytes(); + ByteBuffer bb = ByteBuffer.wrap(bytes); + Charset csets = Charset.forName("UTF-8"); + CharBuffer c = csets.decode(bb); + return c.toString(); + } + + private static boolean isUTF8Encoding(String str) { + byte[] bytes = str.getBytes(); + for (int i = 0; i < bytes.length; i++) { + int byteLen = Byte.toString(bytes[i]).length(); + if (byteLen == 4) + return true; + else + continue; + } + return false; + } + + public static boolean stringToBoolean(String value) { + if (value != null) { + value = value.toLowerCase(); + + if (value.equals("t")) { + return true; + } + else if (value.equals("y")) { + return true; + } + else if (value.equals("true")) { + return true; + } + else if (value.equals("yes")) { + return true; + } + else { + return false; + } + } + else + return false; + } + + public static int stringToInt(String value, int defaultValue) { + if (value != null) { + try { + Double doubleValue = Double.valueOf(value); + return doubleValue.intValue(); + } + catch (Exception e) { + return defaultValue; + } + } + else + return defaultValue; + } + + public static BigDecimal stringToBigDecimal(String value, BigDecimal defaultValue) { + if (value == null) { + return defaultValue; + } + + try { + BigDecimal decimalValue = BigDecimal.valueOf(Double.valueOf(value)); + return decimalValue; + } + catch (Exception e) { + return defaultValue; + } + } + + public static Date StringToDate(String str) throws ParseException { + if (Util.isEmptyStr(str)) { + return null; + } + + Date result = null; + String fomater = null; + str = str.replace('T', ' '); + + if (str.indexOf("/") == 4) { + fomater = "yyyy/MM/dd"; + } + else if (str.indexOf("/") == 2 || str.indexOf("/") == 1) { + fomater = "MM/dd/yyyy"; + } + else if (str.indexOf("-") == 2 || str.indexOf("-") == 1) { + fomater = "MM-dd-yyyy"; + } + else if (str.indexOf("-") == 4 && str.indexOf(":") < 0) { + fomater = "yyyy-MM-dd"; + } + else if (str.indexOf("-") == 4 && str.indexOf(":") > 0) { + if (str.split(":").length == 3) { + fomater = "yyyy-MM-dd HH:mm:ss"; + } + else { + str = str + ":00"; + fomater = "yyyy-MM-dd HH:mm:00"; + } + + } + else if (str.indexOf(".") == 2 || str.indexOf(".") == 1) { + fomater = "MM.dd.yyyy"; + } + else if (str.indexOf(".") == 4) { + fomater = "yyyy.MM.dd"; + } + else if (str.indexOf("-") < 0 && str.indexOf("/") < 0) { + fomater = "yyyyMMdd"; + } + + DateFormat dateFormat = new SimpleDateFormat(fomater); + result = dateFormat.parse(str); + + return result; + } + + public static Date doubleToDate(Double value) throws ParseException { + Date result = null; + + if (value != null) { + if (value > 195000 && value <= 210001) { + value = value * 100 + 01; + } + + if (value >= 19500101 && value <= 21000101) { + String value_Str = String.valueOf(value.intValue()); + result = Util.StringToDate(value_Str); + } + else if (value > (1950 - 1900) * 365 && value < (2100 - 1900) * 365) { + int dateValue = value.intValue(); + double secValue = value - dateValue; + Date dayDate = intToDate(dateValue); + long sec = Math.round(secValue * 24 * 3600 * 1000); + + result = new Date(); + result.setTime(dayDate.getTime() + sec); + return result; + } + } + + return result; + } + + public static Date intToDate(int value) { + Calendar result = Calendar.getInstance(); + result.set(Calendar.YEAR, 1900); + result.set(Calendar.MONTH, 0); + result.set(Calendar.DAY_OF_MONTH, 1); + result.set(Calendar.HOUR_OF_DAY, 0); + result.set(Calendar.MINUTE, 0); + result.set(Calendar.SECOND, 0); + + result.add(Calendar.DATE, value - 2); + return result.getTime(); + } + + public static int getArrayContentSize(Object[] datas) { + int result = 0; + + for (int i = 0; i < datas.length; i++) { + if (datas[i] != null) { + result++; + } + } + + return result; + } + + public static String deleteSuffix(String name) { + String result = null; + + if (!isEmptyStr(name)) { + int pos = name.lastIndexOf("."); + result = name.substring(0, pos); + } + + return result; + } + + public static String[] mergeArray(String[] array1, String[] array2) { + if (array1 == null) { + return array2; + } + + if (array2 == null) { + return array2; + } + + List<String> set = new ArrayList<String>(array1.length + array2.length); + + for (int i = 0; i < array1.length; i++) { + set.add(array1[i]); + } + + for (int i = 0; i < array2.length; i++) { + if (!set.contains(array2[i])) { + set.add(array2[i]); + } + } + + String[] result = new String[0]; + return set.toArray(result); + } + + public static String newOracleDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "to_date('" + nowStr + "','YYYY-MM-DD HH24:MI:SS')"; + } + + public static String newMySqlDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "('" + nowStr + "')"; + } + + public static String newSqlServerDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "('" + nowStr + "')"; + } + + public static boolean isSameString(String value1, String value2) { + if (value1 == null) { + if (value2 == null) { + return true; + } + else { + return false; + } + } + else { + if (value2 == null) { + return false; + } + else { + return value1.equals(value2); + } + } + } + + public static boolean isSameStringIgnoreCase(String value1, String value2) { + if (value1 == null) { + if (value2 == null) { + return true; + } + else { + return false; + } + } + else { + if (value2 == null) { + return false; + } + else { + return value1.equalsIgnoreCase(value2); + } + } + } + + public static String toLowerCase(String name, String defaultValue) { + if (name == null) { + return defaultValue; + } + else { + return name.toLowerCase(); + } + } + + public static String getExceptionStack(Exception e) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outStream); + e.printStackTrace(printStream); + + return outStream.toString(); + } + + public static Date getSpecialDayOffToday(int dayCount) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + dayCount); + return calendar.getTime(); + } + + public static String getPassWord(int length) { + int[] array = new int[length]; + char[] chars = new char[length]; + StringBuilder str = new StringBuilder(); + int temp = 0; + for (int i = 0; i < length; i++) { + while (true) { + temp = (int) (Math.random() * 1000); + if (temp >= 48 && temp <= 57) + break; + if (temp >= 65 && temp <= 90) + break; + if (temp >= 97 && temp <= 122) + break; + } + + array[i] = temp; + chars[i] = (char) array[i]; + str.append(chars[i]); + } + + return str.toString(); + } + + public static void main(String[] args) { + System.out.println(getPassWord(10)); + } + + public static String escapeQuoted(String filter) { + if (filter == null) { + return filter; + } + + int length = filter.length(); + + if (length <= 1) { + return filter; + } + + char first = filter.charAt(0); + char last = filter.charAt(length - 1); + + if (('\'' == first || '"' == first) && (first == last)) { + filter = filter.substring(1, length - 1); + filter = filter.trim(); + return filter; + } + + return filter; + } + + public static int[] getCurYearMonth() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + return new int[] { year, month }; + } + + public static String getTimeStamp(Date date) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateFormat.format(date); + } + + public static String getFileExt(String filename) { + int pos = filename.lastIndexOf("."); + String ext = filename.substring(pos); + return ext; + } + + public static int getMonth(String value) throws ParseException { + Date date = StringToDate(value); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(Calendar.MONTH) + 1; + } + + public static String joinPath(String internalPath, String itemName) { + public static String joinPath(String parent, String path) { + if (isEmptyStr(parent)) { + return path; + } + + parent = parent.replace("\\", "/"); + path = path.replace("\\", "/"); + + if ('/' == parent.charAt(parent.length() - 1)) { + parent = parent.substring(0, parent.length() - 1); + } + + if ('/' == path.charAt(0)) { + path = path.substring(1); + } + + return parent + "/" + path; + } + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/15/0057b13e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/15/0057b13e876500181663a2994eb26aa3 new file mode 100644 index 0000000..1ea9721 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/15/0057b13e876500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +package foundation.fileupload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/16/60ebbb99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/16/60ebbb99876500181663a2994eb26aa3 new file mode 100644 index 0000000..3e41854 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/16/60ebbb99876500181663a2994eb26aa3 @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/009e3e29876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/009e3e29876500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/009e3e29876500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/20c1dffe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/20c1dffe866500181663a2994eb26aa3 new file mode 100644 index 0000000..aca5fc0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/18/20c1dffe866500181663a2994eb26aa3 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/8029b6d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/8029b6d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..688709e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/8029b6d8866500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/c0d24559e56700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/c0d24559e56700181c5ca0c66caaee5f new file mode 100644 index 0000000..637e6bf --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/19/c0d24559e56700181c5ca0c66caaee5f @@ -0,0 +1,239 @@ +package foundation.file.writer; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.jacob.activeX.ActiveXComponent; +import com.jacob.com.ComThread; +import com.jacob.com.Dispatch; +import com.jacob.com.Variant; + +public class ExcelTranslator { + + private static Logger logger; + + static { + logger = Logger.getLogger(ExcelTranslator.class); + String lineString = + } + + public synchronized static boolean testComActive() { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + xl.invoke("Quit", new Variant[] {}); + return true; + } + + public synchronized static void saveAs07(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAs03(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(18) }, new int[1]); + + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAsXlsb(File sourceFile, File targetFile) { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + Dispatch workbooks = null; + Dispatch workbook = null; + + try { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + //workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + //0--姝e父鎵撳紑锛� 1--淇宸ヤ綔绨匡紱 2--淇鏁版嵁 (涓嶈兘鐢ㄤ簬鎵撳紑07) + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 50-xlsb + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(50) }, new int[1]); + + } + catch (Exception e) { + logger.debug(e); + throw new RuntimeException(e); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + + ComThread.Release(); + } + } + + public static void main(String[] args) { + File sourceFile = new File("D:\\test\\prod.xlsx"); + File targetFile = new File("D:\\test\\test2.xlsx"); + + if (!sourceFile.exists()) { + System.out.println("file not exist:" + sourceFile); + return; + } + + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Object xlo = xl.getObject(); + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + System.out.println("version=" + xl.getProperty("Version")); + System.out.println("version=" + Dispatch.get((Dispatch) xlo, "Version")); + xl.setProperty("Visible", new Variant(true)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); +// workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + System.err.println("ok!"); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + } + finally { + ComThread.Release(); + } + System.err.println("done!"); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/80bf4e598c6500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/80bf4e598c6500181663a2994eb26aa3 new file mode 100644 index 0000000..7337067 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/80bf4e598c6500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/90e0bbe8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/90e0bbe8866500181663a2994eb26aa3 new file mode 100644 index 0000000..688709e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/90e0bbe8866500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0ae7ff1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0ae7ff1866500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0ae7ff1866500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1c/400b9204bd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1c/400b9204bd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..a438948 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1c/400b9204bd6700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import foundation.callable.DataPool; +import foundation.data.Entity; +import foundation.fileupload.FileItem; +import foundation.persist.DataHandler; +import foundation.util.Util; +import foundation.variant.Expression; +import foundation.variant.GlobalVariant; +import foundation.variant.VariantContext; +import foundation.variant.VariantRequestParams; +import foundation.variant.VariantSegment; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1e/f03699eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1e/f03699eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..01f2555 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1e/f03699eb866500181663a2994eb26aa3 @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1f/30d399eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1f/30d399eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..866e5af --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/1f/30d399eb866500181663a2994eb26aa3 @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2/1068e697876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2/1068e697876500181663a2994eb26aa3 new file mode 100644 index 0000000..ca25f57 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2/1068e697876500181663a2994eb26aa3 @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple parser intended to parse sequences of name/value pairs. + * Parameter values are exptected to be enclosed in quotes if they + * contain unsafe characters, such as '=' characters or separators. + * Parameter values are optional and can be omitted. + * + * <p> + * <code>param1 = value; param2 = "anything goes; really"; param3</code> + * </p> + * + * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> + */ + +public class ParameterParser { + /** + * String to be parsed. + */ + private char[] chars = null; + + /** + * Current position in the string. + */ + private int pos = 0; + + /** + * Maximum position in the string. + */ + private int len = 0; + + /** + * Start of a token. + */ + private int i1 = 0; + + /** + * End of a token. + */ + private int i2 = 0; + + /** + * Whether names stored in the map should be converted to lower case. + */ + private boolean lowerCaseNames = false; + + /** + * Default ParameterParser constructor. + */ + public ParameterParser() { + super(); + } + + /** + * Are there any characters left to parse? + * + * @return <tt>true</tt> if there are unparsed characters, + * <tt>false</tt> otherwise. + */ + private boolean hasChar() { + return this.pos < this.len; + } + + /** + * A helper method to process the parsed token. This method removes + * leading and trailing blanks as well as enclosing quotation marks, + * when necessary. + * + * @param quoted <tt>true</tt> if quotation marks are expected, + * <tt>false</tt> otherwise. + * @return the token + */ + private String getToken(boolean quoted) { + // Trim leading white spaces + while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { + i2--; + } + // Strip away quotation marks if necessary + if (quoted) { + if (((i2 - i1) >= 2) + && (chars[i1] == '"') + && (chars[i2 - 1] == '"')) { + i1++; + i2--; + } + } + String result = null; + if (i2 > i1) { + result = new String(chars, i1, i2 - i1); + } + return result; + } + + /** + * Tests if the given character is present in the array of characters. + * + * @param ch the character to test for presense in the array of characters + * @param charray the array of characters to test against + * + * @return <tt>true</tt> if the character is present in the array of + * characters, <tt>false</tt> otherwise. + */ + private boolean isOneOf(char ch, final char[] charray) { + boolean result = false; + for (int i = 0; i < charray.length; i++) { + if (ch == charray[i]) { + result = true; + break; + } + } + return result; + } + + /** + * Parses out a token until any of the given terminators + * is encountered. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered signify the end of the token + * + * @return the token + */ + private String parseToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + while (hasChar()) { + ch = chars[pos]; + if (isOneOf(ch, terminators)) { + break; + } + i2++; + pos++; + } + return getToken(false); + } + + /** + * Parses out a token until any of the given terminators + * is encountered outside the quotation marks. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered outside the quotation marks signify the end + * of the token + * + * @return the token + */ + private String parseQuotedToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + boolean quoted = false; + boolean charEscaped = false; + while (hasChar()) { + ch = chars[pos]; + if (!quoted && isOneOf(ch, terminators)) { + break; + } + if (!charEscaped && ch == '"') { + quoted = !quoted; + } + charEscaped = (!charEscaped && ch == '\\'); + i2++; + pos++; + + } + return getToken(true); + } + + /** + * Returns <tt>true</tt> if parameter names are to be converted to lower + * case when name/value pairs are parsed. + * + * @return <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * Otherwise returns <tt>false</tt> + */ + public boolean isLowerCaseNames() { + return this.lowerCaseNames; + } + + /** + * Sets the flag if parameter names are to be converted to lower case when + * name/value pairs are parsed. + * + * @param b <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * <tt>false</tt> otherwise. + */ + public void setLowerCaseNames(boolean b) { + this.lowerCaseNames = b; + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. Multiple separators may be specified and + * the earliest found in the input string is used. + * + * @param str the string that contains a sequence of name/value pairs + * @param separators the name/value pairs separators + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char[] separators) { + if (separators == null || separators.length == 0) { + return new HashMap(); + } + char separator = separators[0]; + if (str != null) { + int idx = str.length(); + for (int i = 0; i < separators.length; i++) { + int tmp = str.indexOf(separators[i]); + if (tmp != -1) { + if (tmp < idx) { + idx = tmp; + separator = separators[i]; + } + } + } + } + return parse(str, separator); + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. + * + * @param str the string that contains a sequence of name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char separator) { + if (str == null) { + return new HashMap(); + } + return parse(str.toCharArray(), separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final char[] chars, char separator) { + if (chars == null) { + return new HashMap(); + } + return parse(chars, 0, chars.length, separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param offset - the initial offset. + * @param length - the length. + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse( + final char[] chars, + int offset, + int length, + char separator) { + + if (chars == null) { + return new HashMap(); + } + HashMap params = new HashMap(); + this.chars = chars; + this.pos = offset; + this.len = length; + + String paramName = null; + String paramValue = null; + while (hasChar()) { + paramName = parseToken(new char[] { + '=', separator }); + paramValue = null; + if (hasChar() && (chars[pos] == '=')) { + pos++; // skip '=' + paramValue = parseQuotedToken(new char[] { + separator }); + } + if (hasChar() && (chars[pos] == separator)) { + pos++; // skip separator + } + if ((paramName != null) && (paramName.length() > 0)) { + if (this.lowerCaseNames) { + paramName = paramName.toLowerCase(); + } + params.put(paramName, paramValue); + } + } + return params; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/80c0c625a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/80c0c625a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..22d5bef --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/80c0c625a46700181c5ca0c66caaee5f @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; +import java.io.IOException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/a0b33d29876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/a0b33d29876500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/a0b33d29876500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/d08bba99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/d08bba99876500181663a2994eb26aa3 new file mode 100644 index 0000000..c1742ab --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/22/d08bba99876500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/004ccf25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/004ccf25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..f426af2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/004ccf25a46700181c5ca0c66caaee5f @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/00c7aba6e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/00c7aba6e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..734a67a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/24/00c7aba6e46700181c5ca0c66caaee5f @@ -0,0 +1,76 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + @Override + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/804a3321876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/804a3321876500181663a2994eb26aa3 new file mode 100644 index 0000000..ffaeade --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/804a3321876500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 util.copy; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/90d0f02c876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/90d0f02c876500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/25/90d0f02c876500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/26/3026a1eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/26/3026a1eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..7bbff00 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/26/3026a1eb866500181663a2994eb26aa3 @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/27/50dac325a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/27/50dac325a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..b9f7777 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/27/50dac325a46700181c5ca0c66caaee5f @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/80fe5801876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/80fe5801876500181663a2994eb26aa3 new file mode 100644 index 0000000..8c3289b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/80fe5801876500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0d7d697876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0d7d697876500181663a2994eb26aa3 new file mode 100644 index 0000000..3c9c983 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0d7d697876500181663a2994eb26aa3 @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.DefaultFileItemFactory; +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * foundation.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * foundation.fileupload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/10393221876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/10393221876500181663a2994eb26aa3 new file mode 100644 index 0000000..1e9973c --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/10393221876500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 util.copy; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/1098ef2c876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/1098ef2c876500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2a/1098ef2c876500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2b/d00bbae8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2b/d00bbae8866500181663a2994eb26aa3 new file mode 100644 index 0000000..7de802d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2b/d00bbae8866500181663a2994eb26aa3 @@ -0,0 +1,46 @@ +package foundation.fileupload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/606bbbe8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/606bbbe8866500181663a2994eb26aa3 new file mode 100644 index 0000000..aca5fc0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/606bbbe8866500181663a2994eb26aa3 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/c09a5901876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/c09a5901876500181663a2994eb26aa3 new file mode 100644 index 0000000..7bbff00 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2d/c09a5901876500181663a2994eb26aa3 @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/70a2dbfe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/70a2dbfe866500181663a2994eb26aa3 new file mode 100644 index 0000000..b2821b8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/70a2dbfe866500181663a2994eb26aa3 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c08dd497876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c08dd497876500181663a2994eb26aa3 new file mode 100644 index 0000000..f004fc9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2e/c08dd497876500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2f/c06fd997876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2f/c06fd997876500181663a2994eb26aa3 new file mode 100644 index 0000000..d5d5120 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/2f/c06fd997876500181663a2994eb26aa3 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0a6c925a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0a6c925a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..956da1b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0a6c925a46700181c5ca0c66caaee5f @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/1033da97876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/1033da97876500181663a2994eb26aa3 new file mode 100644 index 0000000..866e5af --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/1033da97876500181663a2994eb26aa3 @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/10679eeb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/10679eeb866500181663a2994eb26aa3 new file mode 100644 index 0000000..eee6cbd --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/30/10679eeb866500181663a2994eb26aa3 @@ -0,0 +1,675 @@ +package foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.MultipartStream.ItemInputStream; +import foundation.fileupload.servlet.ServletFileUpload; +import foundation.fileupload.servlet.ServletRequestContext; +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.FileItemHeadersImpl; +import foundation.fileupload.util.LimitedInputStream; +import foundation.fileupload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/35/c00a6a1fcd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/35/c00a6a1fcd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..5011c32 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/35/c00a6a1fcd6700181c5ca0c66caaee5f @@ -0,0 +1,186 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/36/202a19f2e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/36/202a19f2e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..7303765 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/36/202a19f2e46700181c5ca0c66caaee5f @@ -0,0 +1,87 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import frame.expression.GlobalVariant; +import frame.expression.IVariantRequestListener; +import frame.expression.VariantExistsException; +import frame.expression.VariantRequestParams; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + + @Override + public String getStringValue(String name, VariantRequestParams params) + throws Exception { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/39/a0f0cb25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/39/a0f0cb25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..a2a9f4f --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/39/a0f0cb25a46700181c5ca0c66caaee5f @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/70a72f1e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/70a72f1e876500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/70a72f1e876500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/d0789fa7c36700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/d0789fa7c36700181c5ca0c66caaee5f new file mode 100644 index 0000000..b063c0f --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3b/d0789fa7c36700181c5ca0c66caaee5f @@ -0,0 +1,179 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/005fe197876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/005fe197876500181663a2994eb26aa3 new file mode 100644 index 0000000..460aaa5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/005fe197876500181663a2994eb26aa3 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.PrintStream; +import java.io.PrintWriter; + + +/** + * Exception for errors encountered while processing the request. + * + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @version $Id: FileUploadException.java 551000 2007-06-27 00:59:16Z jochen $ + */ +public class FileUploadException extends Exception { + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { + this(null, null); + } + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { + this(msg, null); + } + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + public void printStackTrace(PrintStream stream) { + super.printStackTrace(stream); + if (cause != null) { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + public void printStackTrace(PrintWriter writer) { + super.printStackTrace(writer); + if (cause != null) { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + public Throwable getCause() { + return cause; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/f0bc5201876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/f0bc5201876500181663a2994eb26aa3 new file mode 100644 index 0000000..01f2555 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3c/f0bc5201876500181663a2994eb26aa3 @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/4077cd25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/4077cd25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..92d3ea0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/4077cd25a46700181c5ca0c66caaee5f @@ -0,0 +1,46 @@ +package frame.upload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/80b8b3d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/80b8b3d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/3d/80b8b3d8866500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4/b02db4d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4/b02db4d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4/b02db4d8866500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/80dec125a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/80dec125a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..8405ac3 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/80dec125a46700181c5ca0c66caaee5f @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import foundation.fileupload.DefaultFileItem; +import foundation.fileupload.FileItem; + +import foundation.fileupload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link foundation.fileupload.FileItemFactory} + * implementation. This implementation creates + * {@link foundation.fileupload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link foundation.fileupload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/f06e2e1e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/f06e2e1e876500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/40/f06e2e1e876500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/42/3003ebb2c36700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/42/3003ebb2c36700181c5ca0c66caaee5f new file mode 100644 index 0000000..6bf464f --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/42/3003ebb2c36700181c5ca0c66caaee5f @@ -0,0 +1,182 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/509571b3e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/509571b3e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..9761d4e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/509571b3e46700181c5ca0c66caaee5f @@ -0,0 +1,26 @@ +package frame.file; + + +public class ActivePeriodLoader extends Preloader { + + @Override + public void load() throws Exception { + NamedSQL namedSQL = NamedSQL.getInstance("getDataSet"); + namedSQL.setTableName("workperiod"); + + EntitySet entitySet = SQLRunner.getEntitySet(namedSQL); + + if (entitySet.isEmpty()) { + throw new Exception("empty active period"); + } + + Entity entity = entitySet.next(); + + String id = entity.getString("id"); + int year = entity.getInteger("year"); + int month = entity.getInteger("month"); + + ActivePeriod.getInstance().init(id, year, month); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/b088ce25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/b088ce25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..9902fc8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/43/b088ce25a46700181c5ca0c66caaee5f @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/900db599876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/900db599876500181663a2994eb26aa3 new file mode 100644 index 0000000..eef5c33 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/900db599876500181663a2994eb26aa3 @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.File; + +import foundation.fileupload.DefaultFileItem; +import foundation.fileupload.FileItem; + +import foundation.fileupload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link foundation.fileupload.FileItemFactory} + * implementation. This implementation creates + * {@link foundation.fileupload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link foundation.fileupload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/e04a80f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/e04a80f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/45/e04a80f1866500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/47/d065cc25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/47/d065cc25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..c9ed0f1 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/47/d065cc25a46700181c5ca0c66caaee5f @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import foundation.fileupload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/48/e075bb25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/48/e075bb25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..f004fc9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/48/e075bb25a46700181c5ca0c66caaee5f @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/49/20712d60c16700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/49/20712d60c16700181c5ca0c66caaee5f new file mode 100644 index 0000000..4837681 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/49/20712d60c16700181c5ca0c66caaee5f @@ -0,0 +1,178 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.file.UploadResult; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = frame.util.Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4c/70a1b999876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4c/70a1b999876500181663a2994eb26aa3 new file mode 100644 index 0000000..d2360f7 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/4c/70a1b999876500181663a2994eb26aa3 @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5/700ac925a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5/700ac925a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..70b31e8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5/700ac925a46700181c5ca0c66caaee5f @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.MultipartStream; +import foundation.fileupload.ProgressListener; + +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * foundation.fileupload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/50/701ddb97876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/50/701ddb97876500181663a2994eb26aa3 new file mode 100644 index 0000000..a342158 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/50/701ddb97876500181663a2994eb26aa3 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; +import java.io.IOException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/406b9ceb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/406b9ceb866500181663a2994eb26aa3 new file mode 100644 index 0000000..a342158 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/406b9ceb866500181663a2994eb26aa3 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; +import java.io.IOException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/b07bcc0cd66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/b07bcc0cd66700181c5ca0c66caaee5f new file mode 100644 index 0000000..0ffea1c --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/b07bcc0cd66700181c5ca0c66caaee5f @@ -0,0 +1,70 @@ +package frame.expression; + +import java.util.ArrayList; +import java.util.List; + + +public abstract class VariantContext implements IVariantRequestListener { + + private List<VariantContext> linkedContextList; + + public VariantContext() { + linkedContextList = new ArrayList<VariantContext>(); + } + + public void setParametersTo(IExpression expression) throws Exception { + doSetParametersTo(expression, true); + } + + void doSetParametersTo(IExpression expression, boolean queryGlabal) throws Exception { + VariantList paramList = expression.getVariantList(); + + //1. on local + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + + //2. on linked + for (VariantContext linked: linkedContextList) { + linked.doSetParametersTo(expression, false); + } + + //3. + if (queryGlabal) { + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = GlobalVariant.getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + } + } + + @Override + public List<String> getVariantNames() { + return null; + } + + @Override + public abstract String getStringValue(String name, VariantRequestParams params) throws Exception; + + public void linkContext(VariantContext context) { + linkedContextList.add(context); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/d0fddefe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/d0fddefe866500181663a2994eb26aa3 new file mode 100644 index 0000000..1ea9721 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/51/d0fddefe866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +package foundation.fileupload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/53/e0343421876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/53/e0343421876500181663a2994eb26aa3 new file mode 100644 index 0000000..6c86ded --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/53/e0343421876500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 util.copy; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/1046b699876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/1046b699876500181663a2994eb26aa3 new file mode 100644 index 0000000..d9209a8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/1046b699876500181663a2994eb26aa3 @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.FileUpload FileUpload} instance (see + * {@link foundation.fileupload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/608381f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/608381f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..aca5fc0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/54/608381f1866500181663a2994eb26aa3 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/56/0090b899876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/56/0090b899876500181663a2994eb26aa3 new file mode 100644 index 0000000..8e82013 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/56/0090b899876500181663a2994eb26aa3 @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple parser intended to parse sequences of name/value pairs. + * Parameter values are exptected to be enclosed in quotes if they + * contain unsafe characters, such as '=' characters or separators. + * Parameter values are optional and can be omitted. + * + * <p> + * <code>param1 = value; param2 = "anything goes; really"; param3</code> + * </p> + * + * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> + */ + +public class ParameterParser { + /** + * String to be parsed. + */ + private char[] chars = null; + + /** + * Current position in the string. + */ + private int pos = 0; + + /** + * Maximum position in the string. + */ + private int len = 0; + + /** + * Start of a token. + */ + private int i1 = 0; + + /** + * End of a token. + */ + private int i2 = 0; + + /** + * Whether names stored in the map should be converted to lower case. + */ + private boolean lowerCaseNames = false; + + /** + * Default ParameterParser constructor. + */ + public ParameterParser() { + super(); + } + + /** + * Are there any characters left to parse? + * + * @return <tt>true</tt> if there are unparsed characters, + * <tt>false</tt> otherwise. + */ + private boolean hasChar() { + return this.pos < this.len; + } + + /** + * A helper method to process the parsed token. This method removes + * leading and trailing blanks as well as enclosing quotation marks, + * when necessary. + * + * @param quoted <tt>true</tt> if quotation marks are expected, + * <tt>false</tt> otherwise. + * @return the token + */ + private String getToken(boolean quoted) { + // Trim leading white spaces + while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { + i2--; + } + // Strip away quotation marks if necessary + if (quoted) { + if (((i2 - i1) >= 2) + && (chars[i1] == '"') + && (chars[i2 - 1] == '"')) { + i1++; + i2--; + } + } + String result = null; + if (i2 > i1) { + result = new String(chars, i1, i2 - i1); + } + return result; + } + + /** + * Tests if the given character is present in the array of characters. + * + * @param ch the character to test for presense in the array of characters + * @param charray the array of characters to test against + * + * @return <tt>true</tt> if the character is present in the array of + * characters, <tt>false</tt> otherwise. + */ + private boolean isOneOf(char ch, final char[] charray) { + boolean result = false; + for (int i = 0; i < charray.length; i++) { + if (ch == charray[i]) { + result = true; + break; + } + } + return result; + } + + /** + * Parses out a token until any of the given terminators + * is encountered. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered signify the end of the token + * + * @return the token + */ + private String parseToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + while (hasChar()) { + ch = chars[pos]; + if (isOneOf(ch, terminators)) { + break; + } + i2++; + pos++; + } + return getToken(false); + } + + /** + * Parses out a token until any of the given terminators + * is encountered outside the quotation marks. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered outside the quotation marks signify the end + * of the token + * + * @return the token + */ + private String parseQuotedToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + boolean quoted = false; + boolean charEscaped = false; + while (hasChar()) { + ch = chars[pos]; + if (!quoted && isOneOf(ch, terminators)) { + break; + } + if (!charEscaped && ch == '"') { + quoted = !quoted; + } + charEscaped = (!charEscaped && ch == '\\'); + i2++; + pos++; + + } + return getToken(true); + } + + /** + * Returns <tt>true</tt> if parameter names are to be converted to lower + * case when name/value pairs are parsed. + * + * @return <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * Otherwise returns <tt>false</tt> + */ + public boolean isLowerCaseNames() { + return this.lowerCaseNames; + } + + /** + * Sets the flag if parameter names are to be converted to lower case when + * name/value pairs are parsed. + * + * @param b <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * <tt>false</tt> otherwise. + */ + public void setLowerCaseNames(boolean b) { + this.lowerCaseNames = b; + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. Multiple separators may be specified and + * the earliest found in the input string is used. + * + * @param str the string that contains a sequence of name/value pairs + * @param separators the name/value pairs separators + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char[] separators) { + if (separators == null || separators.length == 0) { + return new HashMap(); + } + char separator = separators[0]; + if (str != null) { + int idx = str.length(); + for (int i = 0; i < separators.length; i++) { + int tmp = str.indexOf(separators[i]); + if (tmp != -1) { + if (tmp < idx) { + idx = tmp; + separator = separators[i]; + } + } + } + } + return parse(str, separator); + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. + * + * @param str the string that contains a sequence of name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char separator) { + if (str == null) { + return new HashMap(); + } + return parse(str.toCharArray(), separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final char[] chars, char separator) { + if (chars == null) { + return new HashMap(); + } + return parse(chars, 0, chars.length, separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param offset - the initial offset. + * @param length - the length. + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse( + final char[] chars, + int offset, + int length, + char separator) { + + if (chars == null) { + return new HashMap(); + } + HashMap params = new HashMap(); + this.chars = chars; + this.pos = offset; + this.len = length; + + String paramName = null; + String paramValue = null; + while (hasChar()) { + paramName = parseToken(new char[] { + '=', separator }); + paramValue = null; + if (hasChar() && (chars[pos] == '=')) { + pos++; // skip '=' + paramValue = parseQuotedToken(new char[] { + separator }); + } + if (hasChar() && (chars[pos] == separator)) { + pos++; // skip separator + } + if ((paramName != null) && (paramName.length() > 0)) { + if (this.lowerCaseNames) { + paramName = paramName.toLowerCase(); + } + params.put(paramName, paramValue); + } + } + return params; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/57/a05071b0c36700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/57/a05071b0c36700181c5ca0c66caaee5f new file mode 100644 index 0000000..27e583f --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/57/a05071b0c36700181c5ca0c66caaee5f @@ -0,0 +1,181 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.expression.Expression; +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/58/602a9feb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/58/602a9feb866500181663a2994eb26aa3 new file mode 100644 index 0000000..ca25f57 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/58/602a9feb866500181663a2994eb26aa3 @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple parser intended to parse sequences of name/value pairs. + * Parameter values are exptected to be enclosed in quotes if they + * contain unsafe characters, such as '=' characters or separators. + * Parameter values are optional and can be omitted. + * + * <p> + * <code>param1 = value; param2 = "anything goes; really"; param3</code> + * </p> + * + * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> + */ + +public class ParameterParser { + /** + * String to be parsed. + */ + private char[] chars = null; + + /** + * Current position in the string. + */ + private int pos = 0; + + /** + * Maximum position in the string. + */ + private int len = 0; + + /** + * Start of a token. + */ + private int i1 = 0; + + /** + * End of a token. + */ + private int i2 = 0; + + /** + * Whether names stored in the map should be converted to lower case. + */ + private boolean lowerCaseNames = false; + + /** + * Default ParameterParser constructor. + */ + public ParameterParser() { + super(); + } + + /** + * Are there any characters left to parse? + * + * @return <tt>true</tt> if there are unparsed characters, + * <tt>false</tt> otherwise. + */ + private boolean hasChar() { + return this.pos < this.len; + } + + /** + * A helper method to process the parsed token. This method removes + * leading and trailing blanks as well as enclosing quotation marks, + * when necessary. + * + * @param quoted <tt>true</tt> if quotation marks are expected, + * <tt>false</tt> otherwise. + * @return the token + */ + private String getToken(boolean quoted) { + // Trim leading white spaces + while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { + i2--; + } + // Strip away quotation marks if necessary + if (quoted) { + if (((i2 - i1) >= 2) + && (chars[i1] == '"') + && (chars[i2 - 1] == '"')) { + i1++; + i2--; + } + } + String result = null; + if (i2 > i1) { + result = new String(chars, i1, i2 - i1); + } + return result; + } + + /** + * Tests if the given character is present in the array of characters. + * + * @param ch the character to test for presense in the array of characters + * @param charray the array of characters to test against + * + * @return <tt>true</tt> if the character is present in the array of + * characters, <tt>false</tt> otherwise. + */ + private boolean isOneOf(char ch, final char[] charray) { + boolean result = false; + for (int i = 0; i < charray.length; i++) { + if (ch == charray[i]) { + result = true; + break; + } + } + return result; + } + + /** + * Parses out a token until any of the given terminators + * is encountered. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered signify the end of the token + * + * @return the token + */ + private String parseToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + while (hasChar()) { + ch = chars[pos]; + if (isOneOf(ch, terminators)) { + break; + } + i2++; + pos++; + } + return getToken(false); + } + + /** + * Parses out a token until any of the given terminators + * is encountered outside the quotation marks. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered outside the quotation marks signify the end + * of the token + * + * @return the token + */ + private String parseQuotedToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + boolean quoted = false; + boolean charEscaped = false; + while (hasChar()) { + ch = chars[pos]; + if (!quoted && isOneOf(ch, terminators)) { + break; + } + if (!charEscaped && ch == '"') { + quoted = !quoted; + } + charEscaped = (!charEscaped && ch == '\\'); + i2++; + pos++; + + } + return getToken(true); + } + + /** + * Returns <tt>true</tt> if parameter names are to be converted to lower + * case when name/value pairs are parsed. + * + * @return <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * Otherwise returns <tt>false</tt> + */ + public boolean isLowerCaseNames() { + return this.lowerCaseNames; + } + + /** + * Sets the flag if parameter names are to be converted to lower case when + * name/value pairs are parsed. + * + * @param b <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * <tt>false</tt> otherwise. + */ + public void setLowerCaseNames(boolean b) { + this.lowerCaseNames = b; + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. Multiple separators may be specified and + * the earliest found in the input string is used. + * + * @param str the string that contains a sequence of name/value pairs + * @param separators the name/value pairs separators + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char[] separators) { + if (separators == null || separators.length == 0) { + return new HashMap(); + } + char separator = separators[0]; + if (str != null) { + int idx = str.length(); + for (int i = 0; i < separators.length; i++) { + int tmp = str.indexOf(separators[i]); + if (tmp != -1) { + if (tmp < idx) { + idx = tmp; + separator = separators[i]; + } + } + } + } + return parse(str, separator); + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. + * + * @param str the string that contains a sequence of name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char separator) { + if (str == null) { + return new HashMap(); + } + return parse(str.toCharArray(), separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final char[] chars, char separator) { + if (chars == null) { + return new HashMap(); + } + return parse(chars, 0, chars.length, separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param offset - the initial offset. + * @param length - the length. + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse( + final char[] chars, + int offset, + int length, + char separator) { + + if (chars == null) { + return new HashMap(); + } + HashMap params = new HashMap(); + this.chars = chars; + this.pos = offset; + this.len = length; + + String paramName = null; + String paramValue = null; + while (hasChar()) { + paramName = parseToken(new char[] { + '=', separator }); + paramValue = null; + if (hasChar() && (chars[pos] == '=')) { + pos++; // skip '=' + paramValue = parseQuotedToken(new char[] { + separator }); + } + if (hasChar() && (chars[pos] == separator)) { + pos++; // skip separator + } + if ((paramName != null) && (paramName.length() > 0)) { + if (this.lowerCaseNames) { + paramName = paramName.toLowerCase(); + } + params.put(paramName, paramValue); + } + } + return params; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10afc525a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10afc525a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..743b9de --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/10afc525a46700181c5ca0c66caaee5f @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import foundation.fileupload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/407c00bcda6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/407c00bcda6700181c5ca0c66caaee5f new file mode 100644 index 0000000..b2268f8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5a/407c00bcda6700181c5ca0c66caaee5f @@ -0,0 +1,125 @@ +package frame.file.office; + +import java.io.Console; +import java.net.URL; +import java.net.URLEncoder; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.codec.net.URLCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.corba.se.impl.protocol.JIDLLocalCRDImpl; + +import frame.data.DataContext; +import frame.file.FileIOContainer; +import frame.file.UploadResult; +import frame.file.processor.Monitor; +import frame.util.Util; + +public class Engine { + + private static Engine instance; + private static Object locker = new Object(); + private Logger logger; + private ExcelLoader excelLoader; + + private Engine() { + logger = LoggerFactory.getLogger(this.getClass()); + excelLoader = new ExcelLoader(logger); + + } + + public static Engine getInstance() { + synchronized (locker) { + if (instance == null) { + instance = new Engine(); + } + + return instance; + } + } + + public static void download(HttpServletResponse response, String iocode, DataContext dataContext, Map<String, String> parameterProvider) { + getInstance(); + + StringBuilder log = new StringBuilder(); + + try { + new JIDLLocalCRDImpl(orb, scid, ior) + FileIOContainer.load(); + ExcelWriter excelWriter = new ExcelWriter(Monitor.getDownloadProgressor(), parameterProvider); + DownloadResult result = excelWriter.writeOneFile(iocode, dataContext); + + String filename = result.getFilename(); + response.addHeader("Content-Type", "application/octet-stream"); + filename = URLEncoder.encode(filename, "utf-8"); + response.addHeader("Content-Disposition", "attachment;filename=" + filename); + response.TransmitFile(result.getPath()); + } + catch (Exception e) { + JsonBuilder json = new JsonBuilder(); + json.beginObject(); + json.addValue("log", log.toString()); + json.addValue("error", e.getMessage()); + + json.beginArray("detail"); + List<String> details = Monitor.getDownloadProgressor().getMessageList(); + + for (int i = 0; i < details.size(); i++) { + json.addValue(details.get(i)); + } + + json.endArray(); + json.endObject(); + + response.Write(json.ToString()); + } + } + + public static UploadResult upload(String iocode, FileInfo file, HttpServletRequest request) { + UploadResult result = new UploadResult(request); + + result.writeBegin(); + try { + getInstance(); + FileIOContainer.load(); + instance.excelLoader.loadOneFile(result, iocode, file); + } + catch (Exception e){ + result.fail("error", e.getMessage()); + } + finally { + result.writeEnd(); + } + + return result; + } + + public static UploadResult testDataProcess(String iocode, HttpServletRequest request) { + UploadResult result = new UploadResult(request); + + result.writeBegin(); + try { + getInstance(); + instance.excelLoader.testDataProcess(result, iocode); + } + catch (Exception e){ + result.fail("error", e.getMessage()); + } + finally { + result.writeEnd(); + } + + return result; + } + + private void showHelloMessage() { + logger.info("Excel瀵煎叆鏈嶅姟鍣� V1.0宸插惎鍔�"); + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5b/20617b72da6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5b/20617b72da6700181c5ca0c66caaee5f new file mode 100644 index 0000000..c4cae63 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5b/20617b72da6700181c5ca0c66caaee5f @@ -0,0 +1,189 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + //TODO uploadresult changed + + //result.setPath(path); + //result.setTempPath(path); + //TODO event bus? + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5c/8057b799876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5c/8057b799876500181663a2994eb26aa3 new file mode 100644 index 0000000..e71c933 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5c/8057b799876500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5d/00cf9beb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5d/00cf9beb866500181663a2994eb26aa3 new file mode 100644 index 0000000..6262ada --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5d/00cf9beb866500181663a2994eb26aa3 @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + private static final long serialVersionUID = 7922042602454350470L; + private final String name; + + /** + * Creates a new instance. + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { + super(pMessage); + name = pName; + } + + /** + * Returns the invalid file name. + */ + public String getName() { + return name; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5e/b0feb79eda6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5e/b0feb79eda6700181c5ca0c66caaee5f new file mode 100644 index 0000000..1ce487a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5e/b0feb79eda6700181c5ca0c66caaee5f @@ -0,0 +1,548 @@ +package frame.util; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import frame.config.Configer; +import frame.data.DataBaseType; + +public class Util { + + public static final String TRUE = "T"; + public static final String FALSE = "F"; + public static final String String_Return = "\r\n"; + public static final String String_Empty = ""; + + public static String newShortGUID() { + UUID uuid = UUID.randomUUID(); + String strGUID; + String shortGUID; + + strGUID = uuid.toString(); + shortGUID = strGUID.substring(0, 8) + strGUID.substring(9, 13) + strGUID.substring(14, 18) + strGUID.substring(19, 23) + + strGUID.substring(24, 36); + + return shortGUID; + } + + public static String quotedStr(String str) { + if (str != null) + return "'" + str + "'"; + else + return "''"; + } + + public static String doubleQuotedStr(String str) { + if (str != null) + return "\"" + str + "\""; + else + return "\"\""; + } + + public static String quotedLikeStr(String str) { + if (str != null) + return "'%" + str + "%'"; + else + return "''"; + } + + public static String[] split(String str) { + if (str == null) { + return new String[0]; + } + + return str.replace(",", ";").replace("锛�", ";").replace("锛�", ";").split(";"); + } + + public static String newDBDateString() throws Exception { + Date date = new Date(); + return newDBDateString(date); + } + + public static String newDBDateString(Date date) throws Exception { + DataBaseType dbType = Configer.getDataBaseType(); + + if (DataBaseType.Oracle == dbType) { + return newOracleDateString(date); + } + else if (DataBaseType.SQLServer == dbType) { + return newSqlServerDateString(date); + } + else if (DataBaseType.MySQL == dbType) { + return newMySqlDateString(date); + } + else { + return DataTimeToString(date); + } + } + + public static String toOracleDataStr(String dataStr) { + return "to_date('" + dataStr + "','YYYY-MM-DD HH24:MI:SS')"; + } + + public static String toMySQLDateStr(Date value) { + return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss"); + } + + public static String DataTimeToString(Date value) { + return DataTimeToString(value, "yyyy-MM-dd HH:mm:ss"); + } + + public static String DataTimeToString(Date value, String format) { + if (value == null) { + return null; + } + + String result = ""; + DateFormat dateFormat = new SimpleDateFormat(format); + result = dateFormat.format(value); + + return result; + } + + public static String newDateStr() { + return newDateTimeStr("yyyy-MM-dd"); + } + + public static String newDateTimeStr() { + return newDateTimeStr("yyyy-MM-dd kk:mm:ss"); + } + + public static String newDateTimeStr(String fomater) { + return getDateTimeStr(new Date(), fomater); + } + + public static String getDateTimeStr(Date date, String fomater) { + String result = ""; + DateFormat dateFormat = new SimpleDateFormat(fomater); + result = dateFormat.format(date); + + return result; + } + + public static String booleanToStr(boolean value) { + if (value) + return "T"; + else + return "F"; + } + + public static boolean isEmptyStr(Object str) { + boolean result = false; + + if ((str == null) || ("".equals(str))) + result = true; + + return result; + } + + public static String IfEmpetyStr(String str, String value) { + if (isEmptyStr(str)) { + return value; + } + + return str; + } + + public static boolean isNull(String value) { + if ((value == null)) + return true; + + if ("".equals(value)) { + return true; + } + + if (value.length() == 4) { + value = value.toLowerCase(); + return "null".equals(value); + } + + return false; + } + + public static String UTF8decode(String str) { + if (!isUTF8Encoding(str)) + return str; + byte[] bytes = str.getBytes(); + ByteBuffer bb = ByteBuffer.wrap(bytes); + Charset csets = Charset.forName("UTF-8"); + CharBuffer c = csets.decode(bb); + return c.toString(); + } + + private static boolean isUTF8Encoding(String str) { + byte[] bytes = str.getBytes(); + for (int i = 0; i < bytes.length; i++) { + int byteLen = Byte.toString(bytes[i]).length(); + if (byteLen == 4) + return true; + else + continue; + } + return false; + } + + public static boolean stringToBoolean(String value) { + if (value != null) { + value = value.toLowerCase(); + + if (value.equals("t")) { + return true; + } + else if (value.equals("y")) { + return true; + } + else if (value.equals("true")) { + return true; + } + else if (value.equals("yes")) { + return true; + } + else { + return false; + } + } + else + return false; + } + + public static int stringToInt(String value, int defaultValue) { + if (value != null) { + try { + Double doubleValue = Double.valueOf(value); + return doubleValue.intValue(); + } + catch (Exception e) { + return defaultValue; + } + } + else + return defaultValue; + } + + public static BigDecimal stringToBigDecimal(String value, BigDecimal defaultValue) { + if (value == null) { + return defaultValue; + } + + try { + BigDecimal decimalValue = BigDecimal.valueOf(Double.valueOf(value)); + return decimalValue; + } + catch (Exception e) { + return defaultValue; + } + } + + public static Date StringToDate(String str) throws ParseException { + if (Util.isEmptyStr(str)) { + return null; + } + + Date result = null; + String fomater = null; + str = str.replace('T', ' '); + + if (str.indexOf("/") == 4) { + fomater = "yyyy/MM/dd"; + } + else if (str.indexOf("/") == 2 || str.indexOf("/") == 1) { + fomater = "MM/dd/yyyy"; + } + else if (str.indexOf("-") == 2 || str.indexOf("-") == 1) { + fomater = "MM-dd-yyyy"; + } + else if (str.indexOf("-") == 4 && str.indexOf(":") < 0) { + fomater = "yyyy-MM-dd"; + } + else if (str.indexOf("-") == 4 && str.indexOf(":") > 0) { + if (str.split(":").length == 3) { + fomater = "yyyy-MM-dd HH:mm:ss"; + } + else { + str = str + ":00"; + fomater = "yyyy-MM-dd HH:mm:00"; + } + + } + else if (str.indexOf(".") == 2 || str.indexOf(".") == 1) { + fomater = "MM.dd.yyyy"; + } + else if (str.indexOf(".") == 4) { + fomater = "yyyy.MM.dd"; + } + else if (str.indexOf("-") < 0 && str.indexOf("/") < 0) { + fomater = "yyyyMMdd"; + } + + DateFormat dateFormat = new SimpleDateFormat(fomater); + result = dateFormat.parse(str); + + return result; + } + + public static Date doubleToDate(Double value) throws ParseException { + Date result = null; + + if (value != null) { + if (value > 195000 && value <= 210001) { + value = value * 100 + 01; + } + + if (value >= 19500101 && value <= 21000101) { + String value_Str = String.valueOf(value.intValue()); + result = Util.StringToDate(value_Str); + } + else if (value > (1950 - 1900) * 365 && value < (2100 - 1900) * 365) { + int dateValue = value.intValue(); + double secValue = value - dateValue; + Date dayDate = intToDate(dateValue); + long sec = Math.round(secValue * 24 * 3600 * 1000); + + result = new Date(); + result.setTime(dayDate.getTime() + sec); + return result; + } + } + + return result; + } + + public static Date intToDate(int value) { + Calendar result = Calendar.getInstance(); + result.set(Calendar.YEAR, 1900); + result.set(Calendar.MONTH, 0); + result.set(Calendar.DAY_OF_MONTH, 1); + result.set(Calendar.HOUR_OF_DAY, 0); + result.set(Calendar.MINUTE, 0); + result.set(Calendar.SECOND, 0); + + result.add(Calendar.DATE, value - 2); + return result.getTime(); + } + + public static int getArrayContentSize(Object[] datas) { + int result = 0; + + for (int i = 0; i < datas.length; i++) { + if (datas[i] != null) { + result++; + } + } + + return result; + } + + public static String deleteSuffix(String name) { + String result = null; + + if (!isEmptyStr(name)) { + int pos = name.lastIndexOf("."); + result = name.substring(0, pos); + } + + return result; + } + + public static String[] mergeArray(String[] array1, String[] array2) { + if (array1 == null) { + return array2; + } + + if (array2 == null) { + return array2; + } + + List<String> set = new ArrayList<String>(array1.length + array2.length); + + for (int i = 0; i < array1.length; i++) { + set.add(array1[i]); + } + + for (int i = 0; i < array2.length; i++) { + if (!set.contains(array2[i])) { + set.add(array2[i]); + } + } + + String[] result = new String[0]; + return set.toArray(result); + } + + public static String newOracleDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "to_date('" + nowStr + "','YYYY-MM-DD HH24:MI:SS')"; + } + + public static String newMySqlDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "('" + nowStr + "')"; + } + + public static String newSqlServerDateString(Date date) { + String nowStr = ""; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + nowStr = dateFormat.format(date); + + return "('" + nowStr + "')"; + } + + public static boolean isSameString(String value1, String value2) { + if (value1 == null) { + if (value2 == null) { + return true; + } + else { + return false; + } + } + else { + if (value2 == null) { + return false; + } + else { + return value1.equals(value2); + } + } + } + + public static boolean isSameStringIgnoreCase(String value1, String value2) { + if (value1 == null) { + if (value2 == null) { + return true; + } + else { + return false; + } + } + else { + if (value2 == null) { + return false; + } + else { + return value1.equalsIgnoreCase(value2); + } + } + } + + public static String toLowerCase(String name, String defaultValue) { + if (name == null) { + return defaultValue; + } + else { + return name.toLowerCase(); + } + } + + public static String getExceptionStack(Exception e) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outStream); + e.printStackTrace(printStream); + + return outStream.toString(); + } + + public static Date getSpecialDayOffToday(int dayCount) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + dayCount); + return calendar.getTime(); + } + + public static String getPassWord(int length) { + int[] array = new int[length]; + char[] chars = new char[length]; + StringBuilder str = new StringBuilder(); + int temp = 0; + for (int i = 0; i < length; i++) { + while (true) { + temp = (int) (Math.random() * 1000); + if (temp >= 48 && temp <= 57) + break; + if (temp >= 65 && temp <= 90) + break; + if (temp >= 97 && temp <= 122) + break; + } + + array[i] = temp; + chars[i] = (char) array[i]; + str.append(chars[i]); + } + + return str.toString(); + } + + public static void main(String[] args) { + System.out.println(getPassWord(10)); + } + + public static String escapeQuoted(String filter) { + if (filter == null) { + return filter; + } + + int length = filter.length(); + + if (length <= 1) { + return filter; + } + + char first = filter.charAt(0); + char last = filter.charAt(length - 1); + + if (('\'' == first || '"' == first) && (first == last)) { + filter = filter.substring(1, length - 1); + filter = filter.trim(); + return filter; + } + + return filter; + } + + public static int[] getCurYearMonth() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + return new int[] { year, month }; + } + + public static String getTimeStamp(Date date) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateFormat.format(date); + } + + public static String getFileExt(String filename) { + int pos = filename.lastIndexOf("."); + String ext = filename.substring(pos); + return ext; + } + + public static int getMonth(String value) throws ParseException { + Date date = StringToDate(value); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(Calendar.MONTH) + 1; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e0203e7ee66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e0203e7ee66700181c5ca0c66caaee5f new file mode 100644 index 0000000..0353901 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e0203e7ee66700181c5ca0c66caaee5f @@ -0,0 +1,239 @@ +package frame.file.office.excel; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.jacob.activeX.ActiveXComponent; +import com.jacob.com.ComThread; +import com.jacob.com.Dispatch; +import com.jacob.com.Variant; + +public class ExcelTranslator { + + private static Logger logger; + + static { + logger = Logger.getLogger(ExcelTranslator.class); + } + + public synchronized static boolean testComActive() { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + xl.invoke("Quit", new Variant[] {}); + return true; + } + + public synchronized static void saveAs07(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAs03(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(18) }, new int[1]); + + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAsXlsb(File sourceFile, File targetFile) { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + Dispatch workbooks = null; + Dispatch workbook = null; + + try { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + //workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + //0--姝e父鎵撳紑锛� 1--淇宸ヤ綔绨匡紱 2--淇鏁版嵁 (涓嶈兘鐢ㄤ簬鎵撳紑07) + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 50-xlsb + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(50) }, new int[1]); + + } + catch (Exception e) { + logger.debug(e); + throw new RuntimeException(e); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + + ComThread.Release(); + } + } + + public static void main(String[] args) { + File sourceFile = new File("D:\\test\\prod.xlsx"); + File targetFile = new File("D:\\test\\test2.xlsx"); + + if (!sourceFile.exists()) { + System.out.println("file not exist:" + sourceFile); + return; + } + + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Object xlo = xl.getObject(); + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + System.out.println("version=" + xl.getProperty("Version")); + System.out.println("version=" + Dispatch.get((Dispatch) xlo, "Version")); + xl.setProperty("Visible", new Variant(true)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); +// workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + System.err.println("ok!"); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + } + finally { + ComThread.Release(); + } + System.err.println("done!"); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e039c525a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e039c525a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..4d05beb --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/5f/e039c525a46700181c5ca0c66caaee5f @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.FileUpload FileUpload} instance (see + * {@link foundation.fileupload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6/00097dace46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6/00097dace46700181c5ca0c66caaee5f new file mode 100644 index 0000000..ae6bc56 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6/00097dace46700181c5ca0c66caaee5f @@ -0,0 +1,31 @@ +package foundation.file; + +import foundation.config.Preloader; +import foundation.data.Entity; +import foundation.data.EntitySet; +import foundation.persist.sql.NamedSQL; +import foundation.persist.sql.SQLRunner; + +public class ActivePeriodLoader extends Preloader { + + @Override + public void load() throws Exception { + NamedSQL namedSQL = NamedSQL.getInstance("getDataSet"); + namedSQL.setTableName("workperiod"); + + EntitySet entitySet = SQLRunner.getEntitySet(namedSQL); + + if (entitySet.isEmpty()) { + throw new Exception("empty active period"); + } + + Entity entity = entitySet.next(); + + String id = entity.getString("id"); + int year = entity.getInteger("year"); + int month = entity.getInteger("month"); + + ActivePeriod.getInstance().init(id, year, month); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/62/d021e071856500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/62/d021e071856500181663a2994eb26aa3 new file mode 100644 index 0000000..c360401 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/62/d021e071856500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +package frame.file.office; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.format.CellFormatType; + +import frame.data.Entity; +import frame.file.CellDataType; +import frame.file.CellTypes; +import frame.file.IFileload; +import frame.util.Util; + +public class IOMappingItem implements IFileload{ + private String id; + private String parentId; + private String fromField; + private String toField; + private boolean updateIgnore; + private boolean insertIgnore; + private CellDataType[] exportType; + + @Override + public void initLoad(Entity entity) { + // TODO Auto-generated method stub + + } + + private CellDataType[] parseExportType(String exportType) { + //TODO parseExportType + if (Util.isEmptyStr(exportType)) { + return null; + } + + String[] values = Utils.split(exportType); + List<CellDataType> result = new ArrayList<CellDataType>(); + + for (String value : values) { + if (Util.isEmptyStr(value)) { + continue; + } + + CellDataType cellType = CellTypes.toExcelCellType(value); + + if (cellType != null) { + result.add(cellType); + } + } + + return (CellDataType[]) result.toArray(); + } + + public String getId() { + return id; + } + public String getParentId() { + return parentId; + } + public String getFromField() { + return fromField; + } + public String getToField() { + return toField; + } + public boolean isInsertIgnore() { + return insertIgnore; + } + public boolean isUpdateIgnore() { + return updateIgnore; + } + + public CellDataType[] getExportType() { + return exportType; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/63/d03ce897876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/63/d03ce897876500181663a2994eb26aa3 new file mode 100644 index 0000000..94eb2c2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/63/d03ce897876500181663a2994eb26aa3 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.InputStream; +import java.io.IOException; + +/** + * <p>Abstracts access to the request information needed for file uploads. This + * interfsace should be implemented for each type of request that may be + * handled by FileUpload, such as servlets and portlets.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: RequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface RequestContext { + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + String getCharacterEncoding(); + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + String getContentType(); + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + int getContentLength(); + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + InputStream getInputStream() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/65/b05ea2eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/65/b05ea2eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..fe02b63 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/65/b05ea2eb866500181663a2994eb26aa3 @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.FileUpload FileUpload} instance (see + * {@link foundation.fileupload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6b/30e18d0bd66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6b/30e18d0bd66700181c5ca0c66caaee5f new file mode 100644 index 0000000..fa04c53 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6b/30e18d0bd66700181c5ca0c66caaee5f @@ -0,0 +1,70 @@ +package frame.expression; + +import java.util.ArrayList; +import java.util.List; + + +public abstract class VariantContext implements IVariantRequestListener { + + private List<VariantContext> linkedContextList; + + public VariantContext() { + linkedContextList = new ArrayList<VariantContext>(); + } + + public void setParametersTo(IExpression expression) throws Exception { + doSetParametersTo(expression, true); + } + + public void doSetParametersTo(IExpression expression, boolean queryGlabal) throws Exception { + VariantList paramList = expression.getVariantList(); + + //1. on local + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + + //2. on linked + for (VariantContext linked: linkedContextList) { + linked.doSetParametersTo(expression, false); + } + + //3. + if (queryGlabal) { + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = GlobalVariant.getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + } + } + + @Override + public List<String> getVariantNames() { + return null; + } + + @Override + public abstract String getStringValue(String name, VariantRequestParams params) throws Exception; + + public void linkContext(VariantContext context) { + linkedContextList.add(context); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6c/5072d6fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6c/5072d6fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6c/5072d6fe866500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/3085b8e8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/3085b8e8866500181663a2994eb26aa3 new file mode 100644 index 0000000..b2821b8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/3085b8e8866500181663a2994eb26aa3 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50eb7ef1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50eb7ef1866500181663a2994eb26aa3 new file mode 100644 index 0000000..7de802d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50eb7ef1866500181663a2994eb26aa3 @@ -0,0 +1,46 @@ +package foundation.fileupload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/a0273121876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/a0273121876500181663a2994eb26aa3 new file mode 100644 index 0000000..e198a69 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6e/a0273121876500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 util.copy; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6f/f087d5fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6f/f087d5fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/6f/f087d5fe866500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7/b00a4e5cda6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7/b00a4e5cda6700181c5ca0c66caaee5f new file mode 100644 index 0000000..32fa91b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7/b00a4e5cda6700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/70770d9de46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/70770d9de46700181c5ca0c66caaee5f new file mode 100644 index 0000000..46e2bc2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/70770d9de46700181c5ca0c66caaee5f @@ -0,0 +1,80 @@ +package foundation.file; + +import java.util.ArrayList; +import java.util.List; + +import foundation.variant.GlobalVariant; +import foundation.variant.IVariantRequestListener; +import foundation.variant.VariantExistsException; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + @Override + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/c0c378febc6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/c0c378febc6700181c5ca0c66caaee5f new file mode 100644 index 0000000..5e6c372 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/70/c0c378febc6700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package foundation.file; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import foundation.callable.DataPool; +import foundation.data.Entity; +import foundation.fileupload.FileItem; +import foundation.persist.DataHandler; +import foundation.util.Util; +import foundation.variant.Expression; +import foundation.variant.GlobalVariant; +import foundation.variant.VariantContext; +import foundation.variant.VariantRequestParams; +import foundation.variant.VariantSegment; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/20767ef1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/20767ef1866500181663a2994eb26aa3 new file mode 100644 index 0000000..e3abb10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/20767ef1866500181663a2994eb26aa3 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/90842d1e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/90842d1e876500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/90842d1e876500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/c0fde99fd46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/c0fde99fd46700181c5ca0c66caaee5f new file mode 100644 index 0000000..8083fd6 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/71/c0fde99fd46700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + +// UploadResult result = new UploadResult(filecode); +// result.setPath(path); +// result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/e032bae8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/e032bae8866500181663a2994eb26aa3 new file mode 100644 index 0000000..1ea9721 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/e032bae8866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +package foundation.fileupload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/f0e74029876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/f0e74029876500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/72/f0e74029876500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/6086bc67da6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/6086bc67da6700181c5ca0c66caaee5f new file mode 100644 index 0000000..de4f93d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/6086bc67da6700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + //result.setPath(path); + //result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/706f9aeb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/706f9aeb866500181663a2994eb26aa3 new file mode 100644 index 0000000..a9df4d9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/73/706f9aeb866500181663a2994eb26aa3 @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.MultipartStream; +import foundation.fileupload.ProgressListener; + +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * foundation.fileupload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/74/30374c8e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/74/30374c8e876500181663a2994eb26aa3 new file mode 100644 index 0000000..f004fc9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/74/30374c8e876500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/78/306ec825a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/78/306ec825a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..aa2c1ea --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/78/306ec825a46700181c5ca0c66caaee5f @@ -0,0 +1,675 @@ +package frame.upload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.MultipartStream.ItemInputStream; +import foundation.fileupload.servlet.ServletFileUpload; +import foundation.fileupload.servlet.ServletRequestContext; +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.FileItemHeadersImpl; +import foundation.fileupload.util.LimitedInputStream; +import foundation.fileupload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/79/a088defe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/79/a088defe866500181663a2994eb26aa3 new file mode 100644 index 0000000..7de802d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/79/a088defe866500181663a2994eb26aa3 @@ -0,0 +1,46 @@ +package foundation.fileupload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/90eeeb2c876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/90eeeb2c876500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/90eeeb2c876500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a06a5401876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a06a5401876500181663a2994eb26aa3 new file mode 100644 index 0000000..a9df4d9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7d/a06a5401876500181663a2994eb26aa3 @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.MultipartStream; +import foundation.fileupload.ProgressListener; + +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * foundation.fileupload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7e/70eccd25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7e/70eccd25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..7ec092b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7e/70eccd25a46700181c5ca0c66caaee5f @@ -0,0 +1,36 @@ +package frame.upload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40805301876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40805301876500181663a2994eb26aa3 new file mode 100644 index 0000000..866e5af --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/7f/40805301876500181663a2994eb26aa3 @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/80/40a1a362c16700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/80/40a1a362c16700181c5ca0c66caaee5f new file mode 100644 index 0000000..e21ae65 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/80/40a1a362c16700181c5ca0c66caaee5f @@ -0,0 +1,178 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.file.UploadResult; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/20ceb2d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/20ceb2d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..7de802d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/20ceb2d8866500181663a2994eb26aa3 @@ -0,0 +1,46 @@ +package foundation.fileupload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/80607ff1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/80607ff1866500181663a2994eb26aa3 new file mode 100644 index 0000000..1ea9721 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/84/80607ff1866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +package foundation.fileupload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/85/3023b499876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/85/3023b499876500181663a2994eb26aa3 new file mode 100644 index 0000000..0a67535 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/85/3023b499876500181663a2994eb26aa3 @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.DefaultFileItemFactory; +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * foundation.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * foundation.fileupload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/86/908fed93876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/86/908fed93876500181663a2994eb26aa3 new file mode 100644 index 0000000..6957e8e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/86/908fed93876500181663a2994eb26aa3 @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/87/6041b23e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/87/6041b23e876500181663a2994eb26aa3 new file mode 100644 index 0000000..7de802d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/87/6041b23e876500181663a2994eb26aa3 @@ -0,0 +1,46 @@ +package foundation.fileupload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.servlet.ServletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/103ec325a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/103ec325a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..fac1fe2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/103ec325a46700181c5ca0c66caaee5f @@ -0,0 +1,336 @@ +package frame.upload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5035be99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5035be99876500181663a2994eb26aa3 new file mode 100644 index 0000000..97a1961 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5035be99876500181663a2994eb26aa3 @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import foundation.fileupload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/50365101876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/50365101876500181663a2994eb26aa3 new file mode 100644 index 0000000..d5d5120 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/50365101876500181663a2994eb26aa3 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5043b3d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5043b3d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..1ea9721 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/88/5043b3d8866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +package foundation.fileupload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/89/205eb8e8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/89/205eb8e8866500181663a2994eb26aa3 new file mode 100644 index 0000000..2613314 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/89/205eb8e8866500181663a2994eb26aa3 @@ -0,0 +1,336 @@ +package foundation.fileupload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8c/902e9deb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8c/902e9deb866500181663a2994eb26aa3 new file mode 100644 index 0000000..94eb2c2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8c/902e9deb866500181663a2994eb26aa3 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.InputStream; +import java.io.IOException; + +/** + * <p>Abstracts access to the request information needed for file uploads. This + * interfsace should be implemented for each type of request that may be + * handled by FileUpload, such as servlets and portlets.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: RequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface RequestContext { + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + String getCharacterEncoding(); + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + String getContentType(); + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + int getContentLength(); + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + InputStream getInputStream() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8d/c0d5bc99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8d/c0d5bc99876500181663a2994eb26aa3 new file mode 100644 index 0000000..7e8365a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8d/c0d5bc99876500181663a2994eb26aa3 @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + private static final long serialVersionUID = 7922042602454350470L; + private final String name; + + /** + * Creates a new instance. + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { + super(pMessage); + name = pName; + } + + /** + * Returns the invalid file name. + */ + public String getName() { + return name; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8e/f02d5501876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8e/f02d5501876500181663a2994eb26aa3 new file mode 100644 index 0000000..3c9c983 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8e/f02d5501876500181663a2994eb26aa3 @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.DefaultFileItemFactory; +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * foundation.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * foundation.fileupload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8f/f03ab7d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8f/f03ab7d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..b2821b8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/8f/f03ab7d8866500181663a2994eb26aa3 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7052e797876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7052e797876500181663a2994eb26aa3 new file mode 100644 index 0000000..17bee31 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7052e797876500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7084e0fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7084e0fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..d83e28a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9/7084e0fe866500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/90f881f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/90f881f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..688709e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/90f881f1866500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/f0faa2eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/f0faa2eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..d83e28a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/90/f0faa2eb866500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/92/60045771e56700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/92/60045771e56700181c5ca0c66caaee5f new file mode 100644 index 0000000..c070d84 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/92/60045771e56700181c5ca0c66caaee5f @@ -0,0 +1,239 @@ +package frame.file.office.excel; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.jacob.activeX.ActiveXComponent; +import com.jacob.com.ComThread; +import com.jacob.com.Dispatch; +import com.jacob.com.Variant; + +public class ExcelTranslator { + + private static Logger logger; + + static { + logger = Logger.getLogger(ExcelTranslator.class); + String lineString = + } + + public synchronized static boolean testComActive() { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + xl.invoke("Quit", new Variant[] {}); + return true; + } + + public synchronized static void saveAs07(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAs03(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(18) }, new int[1]); + + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAsXlsb(File sourceFile, File targetFile) { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + Dispatch workbooks = null; + Dispatch workbook = null; + + try { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + //workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + //0--姝e父鎵撳紑锛� 1--淇宸ヤ綔绨匡紱 2--淇鏁版嵁 (涓嶈兘鐢ㄤ簬鎵撳紑07) + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 50-xlsb + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(50) }, new int[1]); + + } + catch (Exception e) { + logger.debug(e); + throw new RuntimeException(e); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + + ComThread.Release(); + } + } + + public static void main(String[] args) { + File sourceFile = new File("D:\\test\\prod.xlsx"); + File targetFile = new File("D:\\test\\test2.xlsx"); + + if (!sourceFile.exists()) { + System.out.println("file not exist:" + sourceFile); + return; + } + + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Object xlo = xl.getObject(); + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + System.out.println("version=" + xl.getProperty("Version")); + System.out.println("version=" + Dispatch.get((Dispatch) xlo, "Version")); + xl.setProperty("Visible", new Variant(true)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); +// workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + System.err.println("ok!"); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + } + finally { + ComThread.Release(); + } + System.err.println("done!"); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/603ed8cfe46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/603ed8cfe46700181c5ca0c66caaee5f new file mode 100644 index 0000000..fd29876 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/603ed8cfe46700181c5ca0c66caaee5f @@ -0,0 +1,80 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import frame.expression.GlobalVariant; +import frame.expression.IVariantRequestListener; +import frame.expression.VariantExistsException; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + @Override + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/60bae497876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/60bae497876500181663a2994eb26aa3 new file mode 100644 index 0000000..a9df4d9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/97/60bae497876500181663a2994eb26aa3 @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.MultipartStream; +import foundation.fileupload.ProgressListener; + +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * foundation.fileupload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/98/30d71868da6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/98/30d71868da6700181c5ca0c66caaee5f new file mode 100644 index 0000000..e9ce3a8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/98/30d71868da6700181c5ca0c66caaee5f @@ -0,0 +1,188 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + //TODO uploadresult changed + //result.setPath(path); + //result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9d/10ed5701876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9d/10ed5701876500181663a2994eb26aa3 new file mode 100644 index 0000000..eee6cbd --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/9d/10ed5701876500181663a2994eb26aa3 @@ -0,0 +1,675 @@ +package foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.MultipartStream.ItemInputStream; +import foundation.fileupload.servlet.ServletFileUpload; +import foundation.fileupload.servlet.ServletRequestContext; +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.FileItemHeadersImpl; +import foundation.fileupload.util.LimitedInputStream; +import foundation.fileupload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003db199876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003db199876500181663a2994eb26aa3 new file mode 100644 index 0000000..ece9f44 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a1/003db199876500181663a2994eb26aa3 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.PrintStream; +import java.io.PrintWriter; + + +/** + * Exception for errors encountered while processing the request. + * + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @version $Id: FileUploadException.java 551000 2007-06-27 00:59:16Z jochen $ + */ +public class FileUploadException extends Exception { + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { + this(null, null); + } + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { + this(msg, null); + } + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + public void printStackTrace(PrintStream stream) { + super.printStackTrace(stream); + if (cause != null) { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + public void printStackTrace(PrintWriter writer) { + super.printStackTrace(writer); + if (cause != null) { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + public Throwable getCause() { + return cause; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/0002ddfe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/0002ddfe866500181663a2994eb26aa3 new file mode 100644 index 0000000..17bee31 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/0002ddfe866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/80b9b213bd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/80b9b213bd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..e77bf0a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a4/80b9b213bd6700181c5ca0c66caaee5f @@ -0,0 +1,91 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import foundation.config.Configer; +import foundation.server.PreloadContainer; +import foundation.util.Util; + +public class RepositoryContainer extends PreloadContainer<Repository> { + + private static RepositoryContainer instance; + private Repository defaultRepository; + + public static synchronized RepositoryContainer getInstance() { + if (instance == null) { + instance = new RepositoryContainer(); + } + + return instance; + } + + @Override + public void load() throws Exception { + try { + File file = new File(Configer.getPath_Config(), "repository.xml"); + + logger.debug("load entity file:" + file); + InputStream inputStream = new FileInputStream(file); + + try { + SAXReader reader = new SAXReader(); + Document doc = reader.read(inputStream); + Element root = doc.getRootElement(); + + loadRepositorys(root); + + } catch (DocumentException e) { + logger.error("can not load sql file: " + file); + logger.error(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + catch (Exception e) { + logger.error(e); + } + } + + private void loadRepositorys(Element root) throws Exception { + Iterator<?> iterator = root.elementIterator("repository"); + + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + loadOneRepository(element); + } + } + + private void loadOneRepository(Element element) throws Exception { + String name = element.attributeValue("name"); + String root = element.attributeValue("root"); + boolean isDefault = Util.stringToBoolean(element.attributeValue("default")); + + String path = element.getTextTrim(); + + Repository repository = new Repository(name, root); + repository.setPath(path); + + add(name, repository); + + if (isDefault) { + defaultRepository = repository; + } + } + + public Repository getDefault() { + return defaultRepository; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a6/1099bd99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a6/1099bd99876500181663a2994eb26aa3 new file mode 100644 index 0000000..7cd5976 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/a6/1099bd99876500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import foundation.fileupload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/aa/e0d1d7fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/aa/e0d1d7fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/aa/e0d1d7fe866500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/408db5d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/408db5d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..aca5fc0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/408db5d8866500181663a2994eb26aa3 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/803adefe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/803adefe866500181663a2994eb26aa3 new file mode 100644 index 0000000..e3abb10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ad/803adefe866500181663a2994eb26aa3 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ae/a0db5601876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ae/a0db5601876500181663a2994eb26aa3 new file mode 100644 index 0000000..a342158 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ae/a0db5601876500181663a2994eb26aa3 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; +import java.io.IOException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/af/a0c69feb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/af/a0c69feb866500181663a2994eb26aa3 new file mode 100644 index 0000000..6815b59 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/af/a0c69feb866500181663a2994eb26aa3 @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.DefaultFileItem; +import foundation.fileupload.FileItem; + +import foundation.fileupload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link foundation.fileupload.FileItemFactory} + * implementation. This implementation creates + * {@link foundation.fileupload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link foundation.fileupload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b0/103183f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b0/103183f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..b2821b8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b0/103183f1866500181663a2994eb26aa3 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b09eb6d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b09eb6d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..2613314 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b09eb6d8866500181663a2994eb26aa3 @@ -0,0 +1,336 @@ +package foundation.fileupload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b0ff039ed46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b0ff039ed46700181c5ca0c66caaee5f new file mode 100644 index 0000000..32fa91b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b1/b0ff039ed46700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b2/4082b8f3e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b2/4082b8f3e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..965fb84 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b2/4082b8f3e46700181c5ca0c66caaee5f @@ -0,0 +1,88 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import frame.expression.GlobalVariant; +import frame.expression.IVariantRequestListener; +import frame.expression.VariantExistsException; +import frame.expression.VariantRequestParams; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + + //TODO + @Override + public String getStringValue(String name, VariantRequestParams params) + throws Exception { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/30d0ac99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/30d0ac99876500181663a2994eb26aa3 new file mode 100644 index 0000000..4f6ad84 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/30d0ac99876500181663a2994eb26aa3 @@ -0,0 +1,675 @@ +package frame.fileupload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.MultipartStream.ItemInputStream; +import foundation.fileupload.servlet.ServletFileUpload; +import foundation.fileupload.servlet.ServletRequestContext; +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.FileItemHeadersImpl; +import foundation.fileupload.util.LimitedInputStream; +import foundation.fileupload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/d06a9304bd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/d06a9304bd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..675f058 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b3/d06a9304bd6700181c5ca0c66caaee5f @@ -0,0 +1,91 @@ +package frame.repositoty; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import foundation.config.Configer; +import foundation.server.PreloadContainer; +import foundation.util.Util; + +public class RepositoryContainer extends PreloadContainer<Repository> { + + private static RepositoryContainer instance; + private Repository defaultRepository; + + public static synchronized RepositoryContainer getInstance() { + if (instance == null) { + instance = new RepositoryContainer(); + } + + return instance; + } + + @Override + public void load() throws Exception { + try { + File file = new File(Configer.getPath_Config(), "repository.xml"); + + logger.debug("load entity file:" + file); + InputStream inputStream = new FileInputStream(file); + + try { + SAXReader reader = new SAXReader(); + Document doc = reader.read(inputStream); + Element root = doc.getRootElement(); + + loadRepositorys(root); + + } catch (DocumentException e) { + logger.error("can not load sql file: " + file); + logger.error(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + catch (Exception e) { + logger.error(e); + } + } + + private void loadRepositorys(Element root) throws Exception { + Iterator<?> iterator = root.elementIterator("repository"); + + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + loadOneRepository(element); + } + } + + private void loadOneRepository(Element element) throws Exception { + String name = element.attributeValue("name"); + String root = element.attributeValue("root"); + boolean isDefault = Util.stringToBoolean(element.attributeValue("default")); + + String path = element.getTextTrim(); + + Repository repository = new Repository(name, root); + repository.setPath(path); + + add(name, repository); + + if (isDefault) { + defaultRepository = repository; + } + } + + public Repository getDefault() { + return defaultRepository; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b5/5054dbfe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b5/5054dbfe866500181663a2994eb26aa3 new file mode 100644 index 0000000..2613314 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b5/5054dbfe866500181663a2994eb26aa3 @@ -0,0 +1,336 @@ +package foundation.fileupload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b8/50b1df97876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b8/50b1df97876500181663a2994eb26aa3 new file mode 100644 index 0000000..eee6cbd --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/b8/50b1df97876500181663a2994eb26aa3 @@ -0,0 +1,675 @@ +package foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.MultipartStream.ItemInputStream; +import foundation.fileupload.servlet.ServletFileUpload; +import foundation.fileupload.servlet.ServletRequestContext; +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.FileItemHeadersImpl; +import foundation.fileupload.util.LimitedInputStream; +import foundation.fileupload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0d1c725a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0d1c725a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..003ff52 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0d1c725a46700181c5ca0c66caaee5f @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/be/00dbcc25a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/be/00dbcc25a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..cfbdc10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/be/00dbcc25a46700181c5ca0c66caaee5f @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/30ecaa4cbd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/30ecaa4cbd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..b741d14 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/30ecaa4cbd6700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import foundation.callable.DataPool; +import foundation.data.Entity; +import foundation.fileupload.FileItem; +import foundation.persist.DataHandler; +import foundation.util.Util; +import foundation.variant.Expression; +import foundation.variant.GlobalVariant; +import foundation.variant.VariantContext; +import foundation.variant.VariantRequestParams; +import foundation.variant.VariantSegment; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/70ddaf99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/70ddaf99876500181663a2994eb26aa3 new file mode 100644 index 0000000..a42b1c4 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c/70ddaf99876500181663a2994eb26aa3 @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.MultipartStream; +import foundation.fileupload.ProgressListener; + +import foundation.fileupload.util.Closeable; +import foundation.fileupload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * foundation.fileupload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * foundation.fileupload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f00f5a01876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f00f5a01876500181663a2994eb26aa3 new file mode 100644 index 0000000..fe02b63 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c0/f00f5a01876500181663a2994eb26aa3 @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import foundation.fileupload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.FileUpload FileUpload} instance (see + * {@link foundation.fileupload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c1/9076c425a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c1/9076c425a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..f4ea8c0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c1/9076c425a46700181c5ca0c66caaee5f @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.DefaultFileItemFactory; +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * foundation.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * foundation.fileupload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/5022e297876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/5022e297876500181663a2994eb26aa3 new file mode 100644 index 0000000..6262ada --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/5022e297876500181663a2994eb26aa3 @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + private static final long serialVersionUID = 7922042602454350470L; + private final String name; + + /** + * Creates a new instance. + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { + super(pMessage); + name = pName; + } + + /** + * Returns the invalid file name. + */ + public String getName() { + return name; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/a0f9e0fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/a0f9e0fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..94eb2c2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c2/a0f9e0fe866500181663a2994eb26aa3 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.InputStream; +import java.io.IOException; + +/** + * <p>Abstracts access to the request information needed for file uploads. This + * interfsace should be implemented for each type of request that may be + * handled by FileUpload, such as servlets and portlets.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: RequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface RequestContext { + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + String getCharacterEncoding(); + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + String getContentType(); + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + int getContentLength(); + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + InputStream getInputStream() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c4/d007dc97876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c4/d007dc97876500181663a2994eb26aa3 new file mode 100644 index 0000000..01f2555 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c4/d007dc97876500181663a2994eb26aa3 @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c6/c00c56b5e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c6/c00c56b5e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..cf85e2a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/c6/c00c56b5e46700181c5ca0c66caaee5f @@ -0,0 +1,30 @@ +package frame.file; + +import frame.data.Entity; +import frame.data.EntitySet; +import frame.persist.NamedSQL; + + +public class ActivePeriodLoader extends Preloader { + + @Override + public void load() throws Exception { + NamedSQL namedSQL = NamedSQL.getInstance("getDataSet"); + namedSQL.setTableName("workperiod"); + + EntitySet entitySet = SQLRunner.getEntitySet(namedSQL); + + if (entitySet.isEmpty()) { + throw new Exception("empty active period"); + } + + Entity entity = entitySet.next(); + + String id = entity.getString("id"); + int year = entity.getInteger("year"); + int month = entity.getInteger("month"); + + ActivePeriod.getInstance().init(id, year, month); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ca/a035d7fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ca/a035d7fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ca/a035d7fe866500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cb/70acd897876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cb/70acd897876500181663a2994eb26aa3 new file mode 100644 index 0000000..7bbff00 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cb/70acd897876500181663a2994eb26aa3 @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cc/5001bfb8e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cc/5001bfb8e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..cec7e72 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cc/5001bfb8e46700181c5ca0c66caaee5f @@ -0,0 +1,31 @@ +package frame.file; + +import frame.data.Entity; +import frame.data.EntitySet; +import frame.persist.NamedSQL; +import frame.persist.SQLRunner; + + +public class ActivePeriodLoader extends Preloader { + + @Override + public void load() throws Exception { + NamedSQL namedSQL = NamedSQL.getInstance("getDataSet"); + namedSQL.setTableName("workperiod"); + + EntitySet entitySet = SQLRunner.getEntitySet(namedSQL); + + if (entitySet.isEmpty()) { + throw new Exception("empty active period"); + } + + Entity entity = entitySet.next(); + + String id = entity.getString("id"); + int year = entity.getInteger("year"); + int month = entity.getInteger("month"); + + ActivePeriod.getInstance().init(id, year, month); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/309fd597876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/309fd597876500181663a2994eb26aa3 new file mode 100644 index 0000000..6815b59 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/309fd597876500181663a2994eb26aa3 @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.DefaultFileItem; +import foundation.fileupload.FileItem; + +import foundation.fileupload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link foundation.fileupload.FileItemFactory} + * implementation. This implementation creates + * {@link foundation.fileupload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link foundation.fileupload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/70c2a1eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/70c2a1eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..17bee31 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/70c2a1eb866500181663a2994eb26aa3 @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/c085f745876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/c085f745876500181663a2994eb26aa3 new file mode 100644 index 0000000..688709e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cd/c085f745876500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cf/e039378c876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cf/e039378c876500181663a2994eb26aa3 new file mode 100644 index 0000000..d83e28a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/cf/e039378c876500181663a2994eb26aa3 @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link foundation.fileupload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * foundation.fileupload.DiskFileUpload DiskFileUpload} instance (see + * {@link foundation.fileupload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/c0329beb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/c0329beb866500181663a2994eb26aa3 new file mode 100644 index 0000000..3c9c983 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/c0329beb866500181663a2994eb26aa3 @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import foundation.fileupload.DefaultFileItemFactory; +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * foundation.fileupload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * foundation.fileupload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/d00ab2d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/d00ab2d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..e3abb10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d/d00ab2d8866500181663a2994eb26aa3 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/404df645876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/404df645876500181663a2994eb26aa3 new file mode 100644 index 0000000..aca5fc0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/404df645876500181663a2994eb26aa3 @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import foundation.fileupload.portlet.PortletRequestContext; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileItemIterator; +import foundation.fileupload.FileUpload; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/d06b1ea1e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/d06b1ea1e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..31a3711 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/d06b1ea1e46700181c5ca0c66caaee5f @@ -0,0 +1,80 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import foundation.variant.GlobalVariant; +import foundation.variant.IVariantRequestListener; +import foundation.variant.VariantExistsException; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + @Override + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/e0b8301e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/e0b8301e876500181663a2994eb26aa3 new file mode 100644 index 0000000..e468dd5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d1/e0b8301e876500181663a2994eb26aa3 @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import foundation.fileupload.FileItemHeaders; + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d2/3090705cc16700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d2/3090705cc16700181c5ca0c66caaee5f new file mode 100644 index 0000000..fc4235e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d2/3090705cc16700181c5ca0c66caaee5f @@ -0,0 +1,188 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import foundation.callable.DataPool; +import foundation.data.Entity; +import foundation.fileupload.FileItem; +import foundation.persist.DataHandler; +import foundation.util.Util; +import foundation.variant.Expression; +import foundation.variant.GlobalVariant; +import foundation.variant.VariantContext; +import foundation.variant.VariantRequestParams; +import foundation.variant.VariantSegment; +import frame.file.UploadResult; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = frame.util.Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/0097b803c46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/0097b803c46700181c5ca0c66caaee5f new file mode 100644 index 0000000..c62eb7c --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/0097b803c46700181c5ca0c66caaee5f @@ -0,0 +1,184 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.activation.DataHandler; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b02a3608d66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b02a3608d66700181c5ca0c66caaee5f new file mode 100644 index 0000000..72fa9ea --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b02a3608d66700181c5ca0c66caaee5f @@ -0,0 +1,70 @@ +package frame.expression; + +import java.util.ArrayList; +import java.util.List; + + +public abstract class VariantContext implements IVariantRequestListener { + + private List<VariantContext> linkedContextList; + + public VariantContext() { + linkedContextList = new ArrayList<VariantContext>(); + } + + public void setParametersTo(IExpression expression) throws Exception { + doSetParametersTo(expression, true); + } + + protected void doSetParametersTo(IExpression expression, boolean queryGlabal) throws Exception { + VariantList paramList = expression.getVariantList(); + + //1. on local + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + + //2. on linked + for (VariantContext linked: linkedContextList) { + linked.doSetParametersTo(expression, false); + } + + //3. + if (queryGlabal) { + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = GlobalVariant.getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + } + } + + @Override + public List<String> getVariantNames() { + return null; + } + + @Override + public abstract String getStringValue(String name, VariantRequestParams params) throws Exception; + + public void linkContext(VariantContext context) { + linkedContextList.add(context); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09a98eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09a98eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..d5d5120 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d6/b09a98eb866500181663a2994eb26aa3 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d7/d09482f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d7/d09482f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..2613314 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d7/d09482f1866500181663a2994eb26aa3 @@ -0,0 +1,336 @@ +package foundation.fileupload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b083215b8c6500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b083215b8c6500181663a2994eb26aa3 new file mode 100644 index 0000000..7f43c91 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b083215b8c6500181663a2994eb26aa3 @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/e0a2b4d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/e0a2b4d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d8/e0a2b4d8866500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d052b33e876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d052b33e876500181663a2994eb26aa3 new file mode 100644 index 0000000..e3abb10 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/d9/d052b33e876500181663a2994eb26aa3 @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import foundation.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/dd/6027b299876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/dd/6027b299876500181663a2994eb26aa3 new file mode 100644 index 0000000..3d1018f --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/dd/6027b299876500181663a2994eb26aa3 @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/de/e0233b58c16700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/de/e0233b58c16700181c5ca0c66caaee5f new file mode 100644 index 0000000..a272c92 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/de/e0233b58c16700181c5ca0c66caaee5f @@ -0,0 +1,188 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import foundation.callable.DataPool; +import foundation.data.Entity; +import foundation.fileupload.FileItem; +import foundation.persist.DataHandler; +import foundation.util.Util; +import foundation.variant.Expression; +import foundation.variant.GlobalVariant; +import foundation.variant.VariantContext; +import foundation.variant.VariantRequestParams; +import foundation.variant.VariantSegment; +import frame.file.UploadResult; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/df/30537ac6e46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/df/30537ac6e46700181c5ca0c66caaee5f new file mode 100644 index 0000000..e216a42 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/df/30537ac6e46700181c5ca0c66caaee5f @@ -0,0 +1,79 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import frame.expression.GlobalVariant; +import frame.expression.VariantExistsException; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + @Override + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e1/70af3f29876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e1/70af3f29876500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e1/70af3f29876500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/00f9b470da6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/00f9b470da6700181c5ca0c66caaee5f new file mode 100644 index 0000000..2fc3dc9 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/00f9b470da6700181c5ca0c66caaee5f @@ -0,0 +1,189 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + //TODO uploadresult changed + + //result.setPath(path); + //result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/50237afebc6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/50237afebc6700181c5ca0c66caaee5f new file mode 100644 index 0000000..5c1fbbd --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e2/50237afebc6700181c5ca0c66caaee5f @@ -0,0 +1,91 @@ +package foundation.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import foundation.config.Configer; +import foundation.server.PreloadContainer; +import foundation.util.Util; + +public class RepositoryContainer extends PreloadContainer<Repository> { + + private static RepositoryContainer instance; + private Repository defaultRepository; + + public static synchronized RepositoryContainer getInstance() { + if (instance == null) { + instance = new RepositoryContainer(); + } + + return instance; + } + + @Override + public void load() throws Exception { + try { + File file = new File(Configer.getPath_Config(), "repository.xml"); + + logger.debug("load entity file:" + file); + InputStream inputStream = new FileInputStream(file); + + try { + SAXReader reader = new SAXReader(); + Document doc = reader.read(inputStream); + Element root = doc.getRootElement(); + + loadRepositorys(root); + + } catch (DocumentException e) { + logger.error("can not load sql file: " + file); + logger.error(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + catch (Exception e) { + logger.error(e); + } + } + + private void loadRepositorys(Element root) throws Exception { + Iterator<?> iterator = root.elementIterator("repository"); + + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + loadOneRepository(element); + } + } + + private void loadOneRepository(Element element) throws Exception { + String name = element.attributeValue("name"); + String root = element.attributeValue("root"); + boolean isDefault = Util.stringToBoolean(element.attributeValue("default")); + + String path = element.getTextTrim(); + + Repository repository = new Repository(name, root); + repository.setPath(path); + + add(name, repository); + + if (isDefault) { + defaultRepository = repository; + } + } + + public Repository getDefault() { + return defaultRepository; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e6/30f2dc97876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e6/30f2dc97876500181663a2994eb26aa3 new file mode 100644 index 0000000..8c3289b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e6/30f2dc97876500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/50895801876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/50895801876500181663a2994eb26aa3 new file mode 100644 index 0000000..6815b59 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/50895801876500181663a2994eb26aa3 @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.File; + +import foundation.fileupload.DefaultFileItem; +import foundation.fileupload.FileItem; + +import foundation.fileupload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link foundation.fileupload.FileItemFactory} + * implementation. This implementation creates + * {@link foundation.fileupload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link foundation.fileupload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/8038ee2c876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/8038ee2c876500181663a2994eb26aa3 new file mode 100644 index 0000000..d16aff0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e7/8038ee2c876500181663a2994eb26aa3 @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/403581f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/403581f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/403581f1866500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b035c725a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b035c725a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..1ccafd8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b035c725a46700181c5ca0c66caaee5f @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50185601876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50185601876500181663a2994eb26aa3 new file mode 100644 index 0000000..6262ada --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50185601876500181663a2994eb26aa3 @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + private static final long serialVersionUID = 7922042602454350470L; + private final String name; + + /** + * Creates a new instance. + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { + super(pMessage); + name = pName; + } + + /** + * Returns the invalid file name. + */ + public String getName() { + return name; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/700e8875e66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/700e8875e66700181c5ca0c66caaee5f new file mode 100644 index 0000000..c762711 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/eb/700e8875e66700181c5ca0c66caaee5f @@ -0,0 +1,238 @@ +package frame.file.office.excel; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.jacob.activeX.ActiveXComponent; +import com.jacob.com.ComThread; +import com.jacob.com.Dispatch; +import com.jacob.com.Variant; + +public class ExcelTranslator { + + private static Logger logger; + + static { + logger = Logger.getLogger(ExcelTranslator.class); + } + + public synchronized static boolean testComActive() { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + xl.invoke("Quit", new Variant[] {}); + return true; + } + + public synchronized static void saveAs07(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAs03(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(18) }, new int[1]); + + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAsXlsb(File sourceFile, File targetFile) { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + Dispatch workbooks = null; + Dispatch workbook = null; + + try { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + //workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + //0--姝e父鎵撳紑锛� 1--淇宸ヤ綔绨匡紱 2--淇鏁版嵁 (涓嶈兘鐢ㄤ簬鎵撳紑07) + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 50-xlsb + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(50) }, new int[1]); + + } + catch (Exception e) { + logger.debug(e); + throw new RuntimeException(e); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + + ComThread.Release(); + } + } + + public static void main(String[] args) { + File sourceFile = new File("D:\\test\\prod.xlsx"); + File targetFile = new File("D:\\test\\test2.xlsx"); + + if (!sourceFile.exists()) { + System.out.println("file not exist:" + sourceFile); + return; + } + + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Object xlo = xl.getObject(); + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + System.out.println("version=" + xl.getProperty("Version")); + System.out.println("version=" + Dispatch.get((Dispatch) xlo, "Version")); + xl.setProperty("Visible", new Variant(true)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); +// workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + System.err.println("ok!"); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + } + finally { + ComThread.Release(); + } + System.err.println("done!"); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/10c080f1866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/10c080f1866500181663a2994eb26aa3 new file mode 100644 index 0000000..6105c54 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/10c080f1866500181663a2994eb26aa3 @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import foundation.fileupload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/4024c625a46700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/4024c625a46700181c5ca0c66caaee5f new file mode 100644 index 0000000..226f564 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/4024c625a46700181c5ca0c66caaee5f @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/508b8c05d26700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/508b8c05d26700181c5ca0c66caaee5f new file mode 100644 index 0000000..32fa91b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ee/508b8c05d26700181c5ca0c66caaee5f @@ -0,0 +1,187 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/c011b399876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/c011b399876500181663a2994eb26aa3 new file mode 100644 index 0000000..0ad5651 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/c011b399876500181663a2994eb26aa3 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; +import java.io.IOException; + +import foundation.fileupload.FileItemStream; +import foundation.fileupload.FileUploadBase; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/e062a0eb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/e062a0eb866500181663a2994eb26aa3 new file mode 100644 index 0000000..8c3289b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/ef/e062a0eb866500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import foundation.fileupload.FileItemFactory; +import foundation.fileupload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link foundation.fileupload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f0/e0775701876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f0/e0775701876500181663a2994eb26aa3 new file mode 100644 index 0000000..460aaa5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f0/e0775701876500181663a2994eb26aa3 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.PrintStream; +import java.io.PrintWriter; + + +/** + * Exception for errors encountered while processing the request. + * + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @version $Id: FileUploadException.java 551000 2007-06-27 00:59:16Z jochen $ + */ +public class FileUploadException extends Exception { + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { + this(null, null); + } + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { + this(msg, null); + } + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + public void printStackTrace(PrintStream stream) { + super.printStackTrace(stream); + if (cause != null) { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + public void printStackTrace(PrintWriter writer) { + super.printStackTrace(writer); + if (cause != null) { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + public Throwable getCause() { + return cause; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/80bdf20bd66700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/80bdf20bd66700181c5ca0c66caaee5f new file mode 100644 index 0000000..3196a16 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/80bdf20bd66700181c5ca0c66caaee5f @@ -0,0 +1,70 @@ +package frame.expression; + +import java.util.ArrayList; +import java.util.List; + + +public abstract class VariantContext implements IVariantRequestListener { + + private List<VariantContext> linkedContextList; + + public VariantContext() { + linkedContextList = new ArrayList<VariantContext>(); + } + + public void setParametersTo(IExpression expression) throws Exception { + doSetParametersTo(expression, true); + } + + p void doSetParametersTo(IExpression expression, boolean queryGlabal) throws Exception { + VariantList paramList = expression.getVariantList(); + + //1. on local + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + + //2. on linked + for (VariantContext linked: linkedContextList) { + linked.doSetParametersTo(expression, false); + } + + //3. + if (queryGlabal) { + for (VariantSegment variant: paramList) { + if (!variant.isEmpty()) { + continue; + } + + String name = variant.getName(); + String value = GlobalVariant.getStringValue(name, null); + + if (value != null) { + variant.setValue(value); + } + } + } + } + + @Override + public List<String> getVariantNames() { + return null; + } + + @Override + public abstract String getStringValue(String name, VariantRequestParams params) throws Exception; + + public void linkContext(VariantContext context) { + linkedContextList.add(context); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/d06df1abc36700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/d06df1abc36700181c5ca0c66caaee5f new file mode 100644 index 0000000..56f8802 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f3/d06df1abc36700181c5ca0c66caaee5f @@ -0,0 +1,180 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.expression.Expression; +import frame.file.UploadResult; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + result.setPath(path); + result.setTempPath(path); + + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f4/9021f648bd6700181c5ca0c66caaee5f b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f4/9021f648bd6700181c5ca0c66caaee5f new file mode 100644 index 0000000..4e2da13 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f4/9021f648bd6700181c5ca0c66caaee5f @@ -0,0 +1,88 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + +public class RepositoryContainer extends PreloadContainer<Repository> { + + private static RepositoryContainer instance; + private Repository defaultRepository; + + public static synchronized RepositoryContainer getInstance() { + if (instance == null) { + instance = new RepositoryContainer(); + } + + return instance; + } + + @Override + public void load() throws Exception { + try { + File file = new File(Configer.getPath_Config(), "repository.xml"); + + logger.debug("load entity file:" + file); + InputStream inputStream = new FileInputStream(file); + + try { + SAXReader reader = new SAXReader(); + Document doc = reader.read(inputStream); + Element root = doc.getRootElement(); + + loadRepositorys(root); + + } catch (DocumentException e) { + logger.error("can not load sql file: " + file); + logger.error(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + catch (Exception e) { + logger.error(e); + } + } + + private void loadRepositorys(Element root) throws Exception { + Iterator<?> iterator = root.elementIterator("repository"); + + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + loadOneRepository(element); + } + } + + private void loadOneRepository(Element element) throws Exception { + String name = element.attributeValue("name"); + String root = element.attributeValue("root"); + boolean isDefault = Util.stringToBoolean(element.attributeValue("default")); + + String path = element.getTextTrim(); + + Repository repository = new Repository(name, root); + repository.setPath(path); + + add(name, repository); + + if (isDefault) { + defaultRepository = repository; + } + } + + public Repository getDefault() { + return defaultRepository; + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/1018b5d8866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/1018b5d8866500181663a2994eb26aa3 new file mode 100644 index 0000000..86711e5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/1018b5d8866500181663a2994eb26aa3 @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import foundation.fileupload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link foundation.fileupload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/a0a6d9fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/a0a6d9fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..ca25f57 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f6/a0a6d9fe866500181663a2994eb26aa3 @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple parser intended to parse sequences of name/value pairs. + * Parameter values are exptected to be enclosed in quotes if they + * contain unsafe characters, such as '=' characters or separators. + * Parameter values are optional and can be omitted. + * + * <p> + * <code>param1 = value; param2 = "anything goes; really"; param3</code> + * </p> + * + * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> + */ + +public class ParameterParser { + /** + * String to be parsed. + */ + private char[] chars = null; + + /** + * Current position in the string. + */ + private int pos = 0; + + /** + * Maximum position in the string. + */ + private int len = 0; + + /** + * Start of a token. + */ + private int i1 = 0; + + /** + * End of a token. + */ + private int i2 = 0; + + /** + * Whether names stored in the map should be converted to lower case. + */ + private boolean lowerCaseNames = false; + + /** + * Default ParameterParser constructor. + */ + public ParameterParser() { + super(); + } + + /** + * Are there any characters left to parse? + * + * @return <tt>true</tt> if there are unparsed characters, + * <tt>false</tt> otherwise. + */ + private boolean hasChar() { + return this.pos < this.len; + } + + /** + * A helper method to process the parsed token. This method removes + * leading and trailing blanks as well as enclosing quotation marks, + * when necessary. + * + * @param quoted <tt>true</tt> if quotation marks are expected, + * <tt>false</tt> otherwise. + * @return the token + */ + private String getToken(boolean quoted) { + // Trim leading white spaces + while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { + i2--; + } + // Strip away quotation marks if necessary + if (quoted) { + if (((i2 - i1) >= 2) + && (chars[i1] == '"') + && (chars[i2 - 1] == '"')) { + i1++; + i2--; + } + } + String result = null; + if (i2 > i1) { + result = new String(chars, i1, i2 - i1); + } + return result; + } + + /** + * Tests if the given character is present in the array of characters. + * + * @param ch the character to test for presense in the array of characters + * @param charray the array of characters to test against + * + * @return <tt>true</tt> if the character is present in the array of + * characters, <tt>false</tt> otherwise. + */ + private boolean isOneOf(char ch, final char[] charray) { + boolean result = false; + for (int i = 0; i < charray.length; i++) { + if (ch == charray[i]) { + result = true; + break; + } + } + return result; + } + + /** + * Parses out a token until any of the given terminators + * is encountered. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered signify the end of the token + * + * @return the token + */ + private String parseToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + while (hasChar()) { + ch = chars[pos]; + if (isOneOf(ch, terminators)) { + break; + } + i2++; + pos++; + } + return getToken(false); + } + + /** + * Parses out a token until any of the given terminators + * is encountered outside the quotation marks. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered outside the quotation marks signify the end + * of the token + * + * @return the token + */ + private String parseQuotedToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + boolean quoted = false; + boolean charEscaped = false; + while (hasChar()) { + ch = chars[pos]; + if (!quoted && isOneOf(ch, terminators)) { + break; + } + if (!charEscaped && ch == '"') { + quoted = !quoted; + } + charEscaped = (!charEscaped && ch == '\\'); + i2++; + pos++; + + } + return getToken(true); + } + + /** + * Returns <tt>true</tt> if parameter names are to be converted to lower + * case when name/value pairs are parsed. + * + * @return <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * Otherwise returns <tt>false</tt> + */ + public boolean isLowerCaseNames() { + return this.lowerCaseNames; + } + + /** + * Sets the flag if parameter names are to be converted to lower case when + * name/value pairs are parsed. + * + * @param b <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * <tt>false</tt> otherwise. + */ + public void setLowerCaseNames(boolean b) { + this.lowerCaseNames = b; + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. Multiple separators may be specified and + * the earliest found in the input string is used. + * + * @param str the string that contains a sequence of name/value pairs + * @param separators the name/value pairs separators + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char[] separators) { + if (separators == null || separators.length == 0) { + return new HashMap(); + } + char separator = separators[0]; + if (str != null) { + int idx = str.length(); + for (int i = 0; i < separators.length; i++) { + int tmp = str.indexOf(separators[i]); + if (tmp != -1) { + if (tmp < idx) { + idx = tmp; + separator = separators[i]; + } + } + } + } + return parse(str, separator); + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. + * + * @param str the string that contains a sequence of name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char separator) { + if (str == null) { + return new HashMap(); + } + return parse(str.toCharArray(), separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final char[] chars, char separator) { + if (chars == null) { + return new HashMap(); + } + return parse(chars, 0, chars.length, separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param offset - the initial offset. + * @param length - the length. + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse( + final char[] chars, + int offset, + int length, + char separator) { + + if (chars == null) { + return new HashMap(); + } + HashMap params = new HashMap(); + this.chars = chars; + this.pos = offset; + this.len = length; + + String paramName = null; + String paramValue = null; + while (hasChar()) { + paramName = parseToken(new char[] { + '=', separator }); + paramValue = null; + if (hasChar() && (chars[pos] == '=')) { + pos++; // skip '=' + paramValue = parseQuotedToken(new char[] { + separator }); + } + if (hasChar() && (chars[pos] == separator)) { + pos++; // skip separator + } + if ((paramName != null) && (paramName.length() > 0)) { + if (this.lowerCaseNames) { + paramName = paramName.toLowerCase(); + } + params.put(paramName, paramValue); + } + } + return params; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/204fbb99876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/204fbb99876500181663a2994eb26aa3 new file mode 100644 index 0000000..0eee127 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/204fbb99876500181663a2994eb26aa3 @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.fileupload; + +import java.io.InputStream; +import java.io.IOException; + +/** + * <p>Abstracts access to the request information needed for file uploads. This + * interfsace should be implemented for each type of request that may be + * handled by FileUpload, such as servlets and portlets.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: RequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface RequestContext { + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + String getCharacterEncoding(); + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + String getContentType(); + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + int getContentLength(); + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + InputStream getInputStream() throws IOException; +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/30f28053876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/30f28053876500181663a2994eb26aa3 new file mode 100644 index 0000000..b2821b8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/f7/30f28053876500181663a2994eb26aa3 @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.disk; + +import java.io.File; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fa/d0ca9deb866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fa/d0ca9deb866500181663a2994eb26aa3 new file mode 100644 index 0000000..460aaa5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fa/d0ca9deb866500181663a2994eb26aa3 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload; + +import java.io.PrintStream; +import java.io.PrintWriter; + + +/** + * Exception for errors encountered while processing the request. + * + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @version $Id: FileUploadException.java 551000 2007-06-27 00:59:16Z jochen $ + */ +public class FileUploadException extends Exception { + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { + this(null, null); + } + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { + this(msg, null); + } + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + public void printStackTrace(PrintStream stream) { + super.printStackTrace(stream); + if (cause != null) { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + public void printStackTrace(PrintWriter writer) { + super.printStackTrace(writer); + if (cause != null) { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + public Throwable getCause() { + return cause; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fd/f0c68253876500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fd/f0c68253876500181663a2994eb26aa3 new file mode 100644 index 0000000..2613314 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fd/f0c68253876500181663a2994eb26aa3 @@ -0,0 +1,336 @@ +package foundation.fileupload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import foundation.fileupload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import foundation.fileupload.FileItem; +import foundation.fileupload.FileItemHeaders; +import foundation.fileupload.FileItemHeadersSupport; +import foundation.fileupload.FileUploadException; +import foundation.fileupload.ParameterParser; +import foundation.fileupload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fe/400fe0fe866500181663a2994eb26aa3 b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fe/400fe0fe866500181663a2994eb26aa3 new file mode 100644 index 0000000..688709e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.history/fe/400fe0fe866500181663a2994eb26aa3 @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 foundation.fileupload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import foundation.fileupload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/2/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/2/history.index new file mode 100644 index 0000000..4325c05 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/2/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/45/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/45/history.index new file mode 100644 index 0000000..5e66998 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/45/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/6/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/6/history.index new file mode 100644 index 0000000..00c4288 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/6/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/9d/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/9d/history.index new file mode 100644 index 0000000..088770b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/9d/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/75/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/75/history.index new file mode 100644 index 0000000..0bc6ec2 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/75/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/history.index new file mode 100644 index 0000000..0028a81 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/2/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/45/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/45/history.index new file mode 100644 index 0000000..3dcc470 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/45/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6/history.index new file mode 100644 index 0000000..0ae7be8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/2/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/2/history.index new file mode 100644 index 0000000..fbee9b5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/2/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/68/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/68/history.index new file mode 100644 index 0000000..3cfd5ee --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/68/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/44/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/44/history.index new file mode 100644 index 0000000..de1c3ab --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/44/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/88/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/88/history.index new file mode 100644 index 0000000..5efcb3d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/88/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/history.index new file mode 100644 index 0000000..a390d9b --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/7c/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/83/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/83/history.index new file mode 100644 index 0000000..b912d3d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/83/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/88/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/88/history.index new file mode 100644 index 0000000..aed6508 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/88/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/2/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/2/history.index new file mode 100644 index 0000000..632748d --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/2/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/45/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/45/history.index new file mode 100644 index 0000000..f2da1ef --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/45/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/6/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/6/history.index new file mode 100644 index 0000000..9780ce8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/6/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/9d/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/9d/history.index new file mode 100644 index 0000000..66f26d5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/9d/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/history.index new file mode 100644 index 0000000..e58bb70 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/6d/ff/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/9d/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/9d/history.index new file mode 100644 index 0000000..0435518 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/e4/9d/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/history.index b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/history.index new file mode 100644 index 0000000..ca40b61 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.indexes/history.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers index 797494b..3489792 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers.snap b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers.snap index 91d6c54..a5d2698 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers.snap +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.markers.snap Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.syncinfo.snap b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.syncinfo.snap index 91d6c54..b9c9ebc 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.syncinfo.snap +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.projects/frame/.syncinfo.snap Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap b/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap index 91d6c54..b9c9ebc 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/178.tree b/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/178.tree deleted file mode 100644 index 941fe3d..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/178.tree +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/179.tree b/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/179.tree new file mode 100644 index 0000000..bb22953 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.root/179.tree Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/source/my/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources index 1acde01..eee88cc 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.resources/.snap b/source/my/.metadata/.plugins/org.eclipse.core.resources/.snap index 4a66114..3ebeea1 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.resources/.snap +++ b/source/my/.metadata/.plugins/org.eclipse.core.resources/.snap Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs index fa2aa81..58f9382 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs +++ b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs @@ -1,4 +1,4 @@ -#Tue May 29 15:54:29 CST 2018 +#Mon Jun 04 11:05:19 CST 2018 org.eclipse.jdt.core.classFormatVersion=TN|6050543721791|6052145721791|snyfr|4|5|5|6050543721729 version=1 eclipse.preferences.version=1 diff --git a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs index a35d7b0..d1c60ea 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs +++ b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs @@ -1,3 +1,3 @@ -#Fri Jun 01 16:00:40 CST 2018 +#Mon Jun 04 09:32:06 CST 2018 eclipse.preferences.version=1 org.eclipse.jdt.launching.PREF_VM_XML=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<vmSettings defaultVM\="1522136081110">\r\n<vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">\r\n<vm id\="1522136081110" name\="jdk1.8" path\="D\:\\jdk1.8"/>\r\n<vm id\="1522227878683" name\="jdk1.7" path\="D\:\\jdk"/>\r\n<vm id\="pulse_com.sun.java.jdk.win32.x86_64_1.6.0.013" javadocURL\="http\://download.oracle.com/javase/6/docs/api/" name\="Sun JDK 1.6.0_13" path\="D\:\\myeclipse\\Common\\binary\\com.sun.java.jdk.win32.x86_64_1.6.0.013"/>\r\n</vmType>\r\n</vmSettings>\r\n diff --git a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.jsp.core.prefs b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.jsp.core.prefs index ccecc95..d2e760b 100644 --- a/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.jsp.core.prefs +++ b/source/my/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.jsp.core.prefs @@ -1,3 +1,3 @@ -#Fri Jun 01 15:19:01 CST 2018 -org.eclipse.jst.jsp.core.taglib.TaglibIndex=CLEAN +#Mon Jun 04 11:06:32 CST 2018 +org.eclipse.jst.jsp.core.taglib.TaglibIndex=DIRTY eclipse.preferences.version=1 diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.core/1019917792.index b/source/my/.metadata/.plugins/org.eclipse.jdt.core/1019917792.index new file mode 100644 index 0000000..fe1f964 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.core/1019917792.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.core/3109331711.index b/source/my/.metadata/.plugins/org.eclipse.jdt.core/3109331711.index index 0b2cc51..ef0c648 100644 --- a/source/my/.metadata/.plugins/org.eclipse.jdt.core/3109331711.index +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.core/3109331711.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.core/3774752620.index b/source/my/.metadata/.plugins/org.eclipse.jdt.core/3774752620.index new file mode 100644 index 0000000..623d3eb --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.core/3774752620.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.core/436671472.index b/source/my/.metadata/.plugins/org.eclipse.jdt.core/436671472.index new file mode 100644 index 0000000..2bb3f89 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.core/436671472.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/source/my/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt index bdb1b90..c060a37 100644 --- a/source/my/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt @@ -1,49 +1,51 @@ INDEX VERSION 1.126+D:\workspace\frame\source\my\.metadata\.plugins\org.eclipse.jdt.core 4159761592.index -1873448748.index -3876082560.index -1953955229.index -2834394663.index -1460243998.index -264491689.index -2659240909.index -4132149500.index -2174883210.index -3190205285.index 3332306884.index -2477370309.index -2916737241.index -39242506.index -3356433732.index -3603037602.index -2586785081.index -1470326161.index 1278621499.index -3109331711.index -786544627.index -2174282507.index -2887624729.index -1324998903.index -1416911754.index -2291213994.index -3940301241.index -3649090703.index -160082151.index -1119080762.index -423418123.index -4115211836.index -1189251053.index 1860173736.index +2834394663.index +3912853835.index +39242506.index +264491689.index +3096149109.index +423418123.index +3109331711.index +1189251053.index +2887624729.index +1602092166.index +2174282507.index +1873448748.index +3356433732.index +4132149500.index +1119080762.index +1470326161.index +2782812272.index +3603037602.index +2477370309.index +2131292812.index 1004964678.index 2854191084.index -3912853835.index -2782812272.index -2131292812.index -4029643150.index -2340564467.index -3233680155.index -1602092166.index -1104993328.index -3096149109.index -513856608.index 3695434936.index +4115211836.index +786544627.index +160082151.index +2916737241.index +4029643150.index +2586785081.index +3774752620.index +2291213994.index +3233680155.index +2340564467.index +3649090703.index +3940301241.index +2659240909.index +1104993328.index +1953955229.index +1416911754.index +513856608.index +3190205285.index +1324998903.index +2174883210.index +3876082560.index +436671472.index +1019917792.index diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml index 3209ba7..f8d999b 100644 --- a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <qualifiedTypeNameHistroy> -<fullyQualifiedTypeName name="com.google.gson.reflect.TypeToken"/> <fullyQualifiedTypeName name="console.BeaconModel"/> <fullyQualifiedTypeName name="java.math.BigDecimal"/> <fullyQualifiedTypeName name="com.sun.java.swing.plaf.windows.resources.windows"/> @@ -60,4 +59,5 @@ <fullyQualifiedTypeName name="java.net.URL"/> <fullyQualifiedTypeName name="java.net.URLEncoder"/> <fullyQualifiedTypeName name="com.sun.corba.se.impl.protocol.JIDLLocalCRDImpl"/> +<fullyQualifiedTypeName name="frame.upload.FileItemHeaders"/> </qualifiedTypeNameHistroy> diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml index 5c391b2..1ee6762 100644 --- a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -21,19 +21,12 @@ <section name="org.eclipse.jdt.internal.ui.wizards.buildpaths.NewVariableEntryDialog"> <item value="577" key="DIALOG_WIDTH"/> <item value="-12" key="DIALOG_Y_ORIGIN"/> - <item value="438" key="DIALOG_HEIGHT"/> <item value="115" key="DIALOG_X_ORIGIN"/> + <item value="438" key="DIALOG_HEIGHT"/> <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> </section> <section name="BuildPathsPropertyPage"> <item value="2" key="pageIndex"/> - </section> - <section name="DialogBounds_SuperInterfaceSelectionDialog"> - <item value="373" key="DIALOG_WIDTH"/> - <item value="-60" key="DIALOG_Y_ORIGIN"/> - <item value="596" key="DIALOG_HEIGHT"/> - <item value="100" key="DIALOG_X_ORIGIN"/> - <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> </section> <section name="JavaSearchPage"> <item value="false" key="CASE_SENSITIVE"/> @@ -43,10 +36,10 @@ <item value="11" key="includeMask"/> <item value="2" key="limitTo"/> <item value="0" key="scope"/> - <item value="" key="javaElement"/> <item value="session" key="pattern"/> - <item value="0" key="matchLocations"/> + <item value="" key="javaElement"/> <item value="0" key="searchFor"/> + <item value="0" key="matchLocations"/> <item value="false" key="isCaseSensitive"/> <list key="workingSets"> </list> @@ -55,10 +48,10 @@ <item value="11" key="includeMask"/> <item value="2" key="limitTo"/> <item value="0" key="scope"/> - <item value="" key="javaElement"/> <item value="taskservice" key="pattern"/> - <item value="0" key="matchLocations"/> + <item value="" key="javaElement"/> <item value="3" key="searchFor"/> + <item value="0" key="matchLocations"/> <item value="false" key="isCaseSensitive"/> <list key="workingSets"> </list> @@ -67,10 +60,10 @@ <item value="11" key="includeMask"/> <item value="2" key="limitTo"/> <item value="0" key="scope"/> - <item value="" key="javaElement"/> <item value="stepsave" key="pattern"/> - <item value="0" key="matchLocations"/> + <item value="" key="javaElement"/> <item value="0" key="searchFor"/> + <item value="0" key="matchLocations"/> <item value="false" key="isCaseSensitive"/> <list key="workingSets"> </list> @@ -79,14 +72,30 @@ <item value="11" key="includeMask"/> <item value="2" key="limitTo"/> <item value="0" key="scope"/> - <item value="" key="javaElement"/> <item value="repsonse" key="pattern"/> - <item value="0" key="matchLocations"/> + <item value="" key="javaElement"/> <item value="0" key="searchFor"/> + <item value="0" key="matchLocations"/> <item value="false" key="isCaseSensitive"/> <list key="workingSets"> </list> </section> + </section> + <section name="DialogBounds_SuperInterfaceSelectionDialog"> + <item value="373" key="DIALOG_WIDTH"/> + <item value="-60" key="DIALOG_Y_ORIGIN"/> + <item value="100" key="DIALOG_X_ORIGIN"/> + <item value="596" key="DIALOG_HEIGHT"/> + <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> + </section> + <section name="ClasspathContainerSelectionPage"> + <item value="1" key="index"/> + </section> + <section name="SourceActionDialog.methods"> + <item value="1" key="VisibilityModifier"/> + <item value="false" key="Comments"/> + <item value="false" key="SynchronizedModifier"/> + <item value="false" key="FinalModifier"/> </section> <section name="ProblemSeveritiesConfigurationBlock"> <item value="false" key="expanded4"/> @@ -97,19 +106,10 @@ <item value="false" key="expanded5"/> <item value="true" key="expanded0"/> </section> - <section name="SourceActionDialog.methods"> - <item value="false" key="Comments"/> - <item value="1" key="VisibilityModifier"/> - <item value="false" key="SynchronizedModifier"/> - <item value="false" key="FinalModifier"/> - </section> - <section name="ClasspathContainerSelectionPage"> - <item value="1" key="index"/> - </section> <section name="org.eclipse.jdt.internal.ui.typehierarchy.QuickHierarchy"> <item value="500" key="org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControlDIALOG_WIDTH"/> - <item value="360" key="org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControlDIALOG_HEIGHT"/> <item value="false" key="org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControlDIALOG_USE_PERSISTED_LOCATION"/> + <item value="360" key="org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControlDIALOG_HEIGHT"/> <item value="true" key="org.eclipse.jdt.internal.ui.typehierarchy.HierarchyInformationControlDIALOG_USE_PERSISTED_SIZE"/> </section> <section name="org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart"> @@ -121,13 +121,13 @@ </section> <section name="JavaElementSearchActions"> </section> - <section name="RenameInformationPopup"> - </section> <section name="SearchInDialog"> <item value="true" key="SearchInJRE"/> <item value="true" key="SearchInProjects"/> <item value="true" key="SearchInAppLibs"/> <item value="true" key="SearchInSources"/> + </section> + <section name="RenameInformationPopup"> </section> <section name="org.eclipse.jdt.internal.ui.text.QuickOutline"> <item value="false" key="GoIntoTopLevelTypeAction.isChecked"/> @@ -143,8 +143,8 @@ <section name="CallHierarchySearchScope"> </section> <section name="SourceActionDialog.constructors"> - <item value="1" key="VisibilityModifier"/> <item value="false" key="Comments"/> + <item value="1" key="VisibilityModifier"/> <item value="false" key="SynchronizedModifier"/> <item value="false" key="FinalModifier"/> </section> @@ -172,8 +172,8 @@ <section name="DialogBoundsSettings"> <item value="600" key="DIALOG_WIDTH"/> <item value="200" key="DIALOG_Y_ORIGIN"/> - <item value="668" key="DIALOG_X_ORIGIN"/> <item value="500" key="DIALOG_HEIGHT"/> + <item value="668" key="DIALOG_X_ORIGIN"/> <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> </section> </section> @@ -183,24 +183,24 @@ <section name="DialogBoundsSettings"> <item value="600" key="DIALOG_WIDTH"/> <item value="4" key="DIALOG_Y_ORIGIN"/> - <item value="-14" key="DIALOG_X_ORIGIN"/> <item value="500" key="DIALOG_HEIGHT"/> + <item value="-14" key="DIALOG_X_ORIGIN"/> <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> </section> + </section> + <section name="completion_proposal_size"> + <item value="870" key="size.x"/> + <item value="276" key="size.y"/> </section> <section name="ExtractMethodWizard"> <item value="false" key="ThrowRuntimeExceptions"/> <item value="false" key="GenerateJavadoc"/> <item value="2" key="AccessModifier"/> </section> - <section name="completion_proposal_size"> - <item value="870" key="size.x"/> - <item value="276" key="size.y"/> - </section> <section name="org.eclipse.ltk.ui.refactoring.settings"> - <item value="false" key="updateQualifiedNames"/> - <item value="*" key="patterns"/> <item value="false" key="renameSubpackages"/> + <item value="*" key="patterns"/> + <item value="false" key="updateQualifiedNames"/> <item value="1" key="updateSimilarElementsMatchStrategy"/> <item value="false" key="updateTextualMatches"/> <item value="false" key="updateSimilarElements"/> diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png new file mode 100644 index 0000000..4768f95 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png new file mode 100644 index 0000000..56554ec --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png new file mode 100644 index 0000000..1fa2c34 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png new file mode 100644 index 0000000..a38aa04 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png new file mode 100644 index 0000000..c1396b1 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/12.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/13.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/13.png new file mode 100644 index 0000000..76faf9a --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/13.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png new file mode 100644 index 0000000..3629023 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png new file mode 100644 index 0000000..9abe3c5 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png new file mode 100644 index 0000000..a6abcd8 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png new file mode 100644 index 0000000..a930fe1 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png new file mode 100644 index 0000000..a95f608 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png new file mode 100644 index 0000000..31311ab --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png new file mode 100644 index 0000000..ebe6698 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png new file mode 100644 index 0000000..38192cf --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.history b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.history new file mode 100644 index 0000000..02c401e --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.history @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<session version="1.0">
<refactoring accessors="true" comment="Delete 9 elements from project 'frame'
- Original project: 'frame'
- Original elements:
 disk
 fileupload
 portlet
 servlet
 util
 DefaultFileItem.java
 ParameterParser.java
 ProgressListener.java
 RequestContext.java" description="Delete elements" element1="util" element2="ParameterParser.java" element3="disk" element4="fileupload" element5="ProgressListener.java" element6="servlet" element7="portlet" element8="DefaultFileItem.java" element9="RequestContext.java" elements="0" flags="589830" id="org.eclipse.jdt.ui.delete" resources="9" stamp="1527849111105" subPackages="false" version="1.0"/>
<refactoring accessors="true" comment="Delete 13 elements from project 'frame'
- Original project: 'frame'
- Original elements:
 DefaultFileItemFactory.java
 DiskFileUpload.java
 FileItem.java
 FileItemFactory.java
 FileItemHeaders.java
 FileItemHeadersSupport.java
 FileItemIterator.java
 FileItemStream.java
 FileUpload.java
 FileUploadBase.java
 FileUploadException.java
 InvalidFileNameException.java
 MultipartStream.java" description="Delete elements" element1="FileItemHeaders.java" element10="DefaultFileItemFactory.java" element11="FileUpload.java" element12="FileItemFactory.java" element13="FileItem.java" element2="FileItemStream.java" element3="FileItemHeadersSupport.java" element4="MultipartStream.java" element5="DiskFileUpload.java" element6="InvalidFileNameException.java" element7="FileItemIterator.java" element8="FileUploadException.java" element9="FileUploadBase.java" elements="0" flags="589830" id="org.eclipse.jdt.ui.delete" resources="13" stamp="1527849115253" subPackages="false" version="1.0"/>
<refactoring comment="Copy package 'util' to 'frame/src/frame.upload'
- Original project: 'frame'
- Destination element: 'frame/src/frame.upload'
- Original element: 'frame/src/util'" description="Copy package" destination="/src<frame.upload" element1="/src<util" flags="589830" fragments="1" id="org.eclipse.jdt.ui.copy" policy="org.eclipse.jdt.ui.copyPackages" stamp="1527849163641" version="1.0"/>
<refactoring accessors="true" comment="Delete element from project 'frame'
- Original project: 'frame'
- Original element: 'frame/src/util.copy'" description="Delete element" element1="/src<util.copy" elements="1" flags="589830" id="org.eclipse.jdt.ui.delete" resources="0" stamp="1527849168696" subPackages="false" version="1.0"/>
<refactoring comment="Copy package 'util' to 'frame/src/frame.upload'
- Original project: 'frame'
- Destination element: 'frame/src/frame.upload'
- Original element: 'frame/src/util'" description="Copy package" destination="/src<frame.upload" element1="/src<util" flags="589830" fragments="1" id="org.eclipse.jdt.ui.copy" policy="org.eclipse.jdt.ui.copyPackages" stamp="1527849182217" version="1.0"/>
<refactoring accessors="true" comment="Delete element from project 'frame'
- Original project: 'frame'
- Original element: 'frame/src/util'" description="Delete element" element1="/src<util" elements="1" flags="589830" id="org.eclipse.jdt.ui.delete" resources="0" stamp="1527849188399" subPackages="false" version="1.0"/>
<refactoring comment="Rename package 'servlet' to 'frame.upload.servlet'
- Original project: 'frame'
- Original element: 'frame/src/servlet'
- Renamed element: 'frame/src/frame.upload.servlet'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'servlet'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<servlet" name="frame.upload.servlet" qualified="false" references="true" stamp="1527849218186" textual="false" version="1.0"/>
<refactoring comment="Rename package 'portlet' to 'frame.upload.portlet'
- Original project: 'frame'
- Original element: 'frame/src/portlet'
- Renamed element: 'frame/src/frame.upload.portlet'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'portlet'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<portlet" name="frame.upload.portlet" qualified="false" references="true" stamp="1527849230385" textual="false" version="1.0"/>
<refactoring comment="Rename package 'fileupload' to 'frame.upload'
- Original project: 'frame'
- Original element: 'frame/src/fileupload'
- Renamed element: 'frame/src/frame.upload'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'fileupload'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<fileupload" name="frame.upload" qualified="false" references="true" stamp="1527849244638" textual="false" version="1.0"/>
<refactoring comment="Rename package 'disk' to 'frame.upload.disk'
- Original project: 'frame'
- Original element: 'frame/src/disk'
- Renamed element: 'frame/src/frame.upload.disk'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'disk'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<disk" name="frame.upload.disk" qualified="false" references="true" stamp="1527849253097" textual="false" version="1.0"/>

</session> \ No newline at end of file diff --git a/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.index b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.index new file mode 100644 index 0000000..5e32822 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/22/refactorings.index @@ -0,0 +1,10 @@ +1527849111105 Delete elements +1527849115253 Delete elements +1527849163641 Copy package +1527849168696 Delete element +1527849182217 Copy package +1527849188399 Delete element +1527849218186 Rename package 'servlet' +1527849230385 Rename package 'portlet' +1527849244638 Rename package 'fileupload' +1527849253097 Rename package 'disk' diff --git a/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.history b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.history new file mode 100644 index 0000000..a0c951c --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.history @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<session version="1.0">
<refactoring comment="Rename package 'frame.reposity' to 'frame.repositoty'
- Original project: 'frame'
- Original element: 'frame/src/frame.reposity'
- Renamed element: 'frame/src/frame.repositoty'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'frame.reposity'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<frame.reposity" name="frame.repositoty" qualified="false" references="true" stamp="1528092205604" textual="false" version="1.0"/>
<refactoring comment="Rename package 'frame.repositoty' to 'frame.file.repositoty'
- Original project: 'frame'
- Original element: 'frame/src/frame.repositoty'
- Renamed element: 'frame/src/frame.file.repositoty'
- Update references to refactored element
- Update textual occurrences in comments and strings" description="Rename package 'frame.repositoty'" flags="589830" hierarchical="false" id="org.eclipse.jdt.ui.rename.package" input="/src<frame.repositoty" name="frame.file.repositoty" qualified="false" references="true" stamp="1528092215816" textual="false" version="1.0"/> +</session> \ No newline at end of file diff --git a/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.index b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.index new file mode 100644 index 0000000..367e622 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/frame/2018/6/23/refactorings.index @@ -0,0 +1,2 @@ +1528092205604 Rename package 'frame.reposity' +1528092215816 Rename package 'frame.repositoty' diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1s_1.del similarity index 100% copy from source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del copy to source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1s_1.del Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t.cfs new file mode 100644 index 0000000..f357238 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t.cfs Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t_1.del similarity index 100% copy from source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del copy to source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1t_1.del Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1u.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1u.cfs new file mode 100644 index 0000000..b8d3ec0 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/_1u.cfs Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments.gen b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments.gen index d2b0d6d..5dec667 100644 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments.gen +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments.gen Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1o b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1o deleted file mode 100644 index 1731ce8..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1o +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1q b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1q new file mode 100644 index 0000000..6d80374 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/2b57b60b1f77f4d89ceff6263fafe157/segments_1q Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1c_1.del similarity index 100% rename from source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del rename to source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1c_1.del Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d.cfs new file mode 100644 index 0000000..cea6119 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d.cfs Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d_1.del similarity index 100% copy from source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k_1.del copy to source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1d_1.del Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1e.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1e.cfs new file mode 100644 index 0000000..14929a3 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/_1e.cfs Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments.gen b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments.gen index 769370e..8346d89 100644 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments.gen +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments.gen Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1a b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1a deleted file mode 100644 index 7426f4e..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1a +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1c b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1c new file mode 100644 index 0000000..f9591dc --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/830bc118332e77292949ed1e6d2fabe0/segments_1c Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k.cfs deleted file mode 100644 index d94d8fa..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_k.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l.cfs deleted file mode 100644 index 151f8ec..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_l_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m.cfs deleted file mode 100644 index caf02a3..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_m_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n.cfs deleted file mode 100644 index 0791f36..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_n_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o.cfs deleted file mode 100644 index 9d05362..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_o_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p.cfs deleted file mode 100644 index 68ab51f..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_p_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q.cfs deleted file mode 100644 index 88a9cf4..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q_1.del b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q_1.del deleted file mode 100644 index 1b473bd..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_q_1.del +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_r.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_r.cfs deleted file mode 100644 index 55e9aed..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_r.cfs +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_u.cfs b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_u.cfs new file mode 100644 index 0000000..3a0db23 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/_u.cfs Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments.gen b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments.gen index cac35d8..ac3900c 100644 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments.gen +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments.gen Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_r b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_r deleted file mode 100644 index c3fe1bf..0000000 --- a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_r +++ /dev/null Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_t b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_t new file mode 100644 index 0000000..aaacda3 --- /dev/null +++ b/source/my/.metadata/.plugins/org.eclipse.m2e.core/nexus/8882244a1f76c291c22b52e8d96ed9e9/segments_t Binary files differ diff --git a/source/my/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/source/my/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml index 01c5e66..225e45b 100644 --- a/source/my/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +++ b/source/my/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <section name="Workbench"> <section name="WorkbenchPreferenceDialogSettings"> - <item value="-326" key="DIALOG_Y_ORIGIN"/> - <item value="449" key="DIALOG_X_ORIGIN"/> + <item value="125" key="DIALOG_Y_ORIGIN"/> + <item value="825" key="DIALOG_X_ORIGIN"/> </section> <section name="NewWizardAction"> <item value="org.eclipse.jdt.ui.wizards.NewEnumCreationWizard" key="NewWizardSelectionPage.STORE_SELECTED_ID"/> @@ -18,8 +18,8 @@ <item value="345" key="DIALOG_WIDTH"/> <item value="org.eclipse.jdt.ui.PackageExplorer" key="ShowViewDialog.STORE_SELECTED_VIEW_ID"/> <item value="233" key="DIALOG_Y_ORIGIN"/> - <item value="796" key="DIALOG_X_ORIGIN"/> <item value="451" key="DIALOG_HEIGHT"/> + <item value="796" key="DIALOG_X_ORIGIN"/> <item value="1|寰蒋闆呴粦|9.0|0|WINDOWS|1|-12|0|0|0|400|0|0|0|1|0|0|0|0|寰蒋闆呴粦" key="DIALOG_FONT_NAME"/> <list key="ShowViewDialog.STORE_EXPANDED_CATEGORIES_ID"> <item value="org.eclipse.jdt.ui.java"/> diff --git a/source/my/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/source/my/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml index 51d0d7d..4855979 100644 --- a/source/my/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml +++ b/source/my/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<workbench progressCount="12" version="2.0"> +<workbench progressCount="14" version="2.0"> <workbenchAdvisor/> <window height="768" maximized="true" width="1024" x="647" y="85"> <fastViewData fastViewLocation="1024"> @@ -49,7 +49,7 @@ <coolItem id="com.genuitec.eclipse.springframework.springconfigeditor" itemType="typePlaceholder" x="-1" y="-1"/> <coolItem id="org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart" itemType="typePlaceholder" x="-1" y="-1"/> <coolItem id="org.eclipse.wst.jsdt.ui.CompilationUnitEditor" itemType="typePlaceholder" x="-1" y="-1"/> -<coolItem id="org.eclipse.jdt.ui.CompilationUnitEditor" itemType="typePlaceholder" x="-1" y="-1"/> +<coolItem id="org.eclipse.jdt.ui.CompilationUnitEditor" itemType="typeToolBarContribution" x="-1" y="-1"/> <coolItem id="com.genuitec.eclipse.webdesigner3.editors.html" itemType="typeToolBarContribution" x="-1" y="-1"/> <coolItem id="group.help" itemType="typeGroupMarker"/> <coolItem id="org.eclipse.ui.workbench.help" itemType="typeToolBarContribution" x="-1" y="-1"/> @@ -59,10 +59,26 @@ <editorArea activeWorkbook="DefaultEditorWorkbook"> <info part="DefaultEditorWorkbook"> <folder appearance="1" expanded="2"> -<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory"/> +<presentation id="org.eclipse.ui.presentations.WorkbenchPresentationFactory"> +<part id="0"/> +<part id="1"/> +<part id="2"/> +</presentation> </folder> </info> </editorArea> +<editor id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Util.java" partName="Util.java" path="D:/workspace/frame/source/my/frame/src/frame/util/Util.java" title="Util.java" tooltip="frame/src/frame/util/Util.java" workbook="DefaultEditorWorkbook"> +<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/frame/src/frame/util/Util.java"/> +<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="2016" selectionTopPixel="855"/> +</editor> +<editor id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Engine.java" partName="Engine.java" path="D:/workspace/frame/source/my/frame/src/frame/file/office/Engine.java" title="Engine.java" tooltip="frame/src/frame/file/office/Engine.java" workbook="DefaultEditorWorkbook"> +<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/frame/src/frame/file/office/Engine.java"/> +<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="762" selectionTopPixel="0"/> +</editor> +<editor activePart="true" focus="true" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="DefaultFileItemFactory.java" partName="DefaultFileItemFactory.java" path="D:/workspace/frame/source/my/frame/src/frame/upload/DefaultFileItemFactory.java" title="DefaultFileItemFactory.java" tooltip="frame/src/frame/upload/DefaultFileItemFactory.java" workbook="DefaultEditorWorkbook"> +<input factoryID="org.eclipse.ui.part.FileEditorInputFactory" path="/frame/src/frame/upload/DefaultFileItemFactory.java"/> +<editorState selectionHorizontalPixel="0" selectionLength="0" selectionOffset="4106" selectionTopPixel="1199"/> +</editor> </editors> <views> <view id="org.eclipse.team.ui.GenericHistoryView" partName="History"> @@ -119,6 +135,9 @@ </view> <view id="org.eclipse.ui.views.ProblemView" partName="Problems"> <viewState PRIMARY_SORT_FIELD="org.eclipse.ui.ide.severityAndDescriptionField" categoryGroup="org.eclipse.ui.ide.severity" markerContentGenerator="org.eclipse.ui.ide.problemsGenerator" partName="Problems"> +<expanded> +<category IMemento.internal.id="Errors"/> +</expanded> <columnWidths org.eclipse.ui.ide.locationField="86" org.eclipse.ui.ide.markerType="90" org.eclipse.ui.ide.pathField="120" org.eclipse.ui.ide.resourceField="159" org.eclipse.ui.ide.severityAndDescriptionField="912"/> <visible IMemento.internal.id="org.eclipse.ui.ide.severityAndDescriptionField"/> <visible IMemento.internal.id="org.eclipse.ui.ide.resourceField"/> @@ -161,7 +180,7 @@ </viewState> </view> </views> -<perspectives activePart="org.eclipse.jdt.ui.PackageExplorer" activePerspective="com.genuitec.myeclipse.perspective.myeclipseperspective"> +<perspectives activePart="org.eclipse.jdt.ui.CompilationUnitEditor" activePerspective="com.genuitec.myeclipse.perspective.myeclipseperspective"> <perspective editorAreaTrimState="2" editorAreaVisible="1" fixed="0" version="0.016"> <descriptor class="org.eclipse.debug.internal.ui.DebugPerspectiveFactory" id="org.eclipse.debug.ui.DebugPerspective" label="Debug"/> <alwaysOnActionSet id="com.genuitec.myeclipse.actions.deploytools"/> @@ -696,7 +715,86 @@ </perspective> </perspectives> <workingSets/> -<navigationHistory/> +<navigationHistory> +<editors> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/call/writer/EnvelopWriter.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/server/Dispatcher.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/file/office/IOMappingItem.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/util/Util.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/file/office/Engine.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/file/office/ExcelHandler.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/upload/DefaultFileItem.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/fileupload/DefaultFileItem.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/upload/DefaultFileItemFactory.java"/> +<editor factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" path="/frame/src/frame/upload/util/FileItemHeadersImpl.java"/> +</editors> +<item historyLabel="EnvelopWriter.java" index="0"> +<position info="not_deleted" x="0" y="0"/> +</item> +<item historyLabel="Dispatcher.java" index="1"> +<position info="not_deleted" x="2305" y="0"/> +</item> +<item historyLabel="IOMappingItem.java" index="2"> +<position info="not_deleted" x="844" y="10"/> +</item> +<item historyLabel="Util.java" index="3"> +<position info="not_deleted" x="1469" y="5"/> +</item> +<item historyLabel="IOMappingItem.java" index="2"> +<position info="not_deleted" x="837" y="0"/> +</item> +<item historyLabel="Util.java" index="3"> +<position info="not_deleted" x="2016" y="0"/> +</item> +<item historyLabel="Engine.java" index="4"> +<position info="not_deleted" x="738" y="0"/> +</item> +<item historyLabel="ExcelHandler.java" index="5"> +<position info="not_deleted" x="1059" y="0"/> +</item> +<item historyLabel="DefaultFileItem.java" index="6"> +<position/> +</item> +<item historyLabel="DefaultFileItem.java" index="7"> +<position info="not_deleted" x="921" y="0"/> +</item> +<item historyLabel="DefaultFileItem.java" index="7"> +<position info="not_deleted" x="900" y="0"/> +</item> +<item historyLabel="DefaultFileItem.java" index="6"> +<position/> +</item> +<item historyLabel="DefaultFileItem.java" index="6"> +<position/> +</item> +<item historyLabel="ExcelHandler.java" index="5"> +<position info="not_deleted" x="1059" y="0"/> +</item> +<item historyLabel="DefaultFileItemFactory.java" index="8"> +<position info="not_deleted" x="4" y="0"/> +</item> +<item historyLabel="ExcelHandler.java" index="5"> +<position info="not_deleted" x="1059" y="0"/> +</item> +<item historyLabel="Engine.java" index="4"> +<position info="not_deleted" x="762" y="0"/> +</item> +<item historyLabel="DefaultFileItem.java" index="6"> +<position info="not_deleted" x="1659" y="0"/> +</item> +<item historyLabel="Engine.java" index="4"> +<position info="not_deleted" x="762" y="0"/> +</item> +<item historyLabel="DefaultFileItemFactory.java" index="8"> +<position info="not_deleted" x="4" y="0"/> +</item> +<item historyLabel="FileItemHeadersImpl.java" index="9"> +<position info="not_deleted" x="1175" y="0"/> +</item> +<item active="true" historyLabel="DefaultFileItemFactory.java" index="8"> +<position info="not_deleted" x="4" y="0"/> +</item> +</navigationHistory> <input factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/" type="8"/> </page> <workbenchWindowAdvisor/> @@ -713,6 +811,33 @@ </trimLayout> </window> <mruList> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="FileItemHeadersImpl.java" tooltip="frame/src/frame/upload/util/FileItemHeadersImpl.java"> +<persistable path="/frame/src/frame/upload/util/FileItemHeadersImpl.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="DefaultFileItemFactory.java" tooltip="frame/src/frame/upload/DefaultFileItemFactory.java"> +<persistable path="/frame/src/frame/upload/DefaultFileItemFactory.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="DefaultFileItem.java" tooltip="frame/src/frame/upload/DefaultFileItem.java"> +<persistable path="/frame/src/frame/upload/DefaultFileItem.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="ExcelHandler.java" tooltip="frame/src/frame/file/office/ExcelHandler.java"> +<persistable path="/frame/src/frame/file/office/ExcelHandler.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Engine.java" tooltip="frame/src/frame/file/office/Engine.java"> +<persistable path="/frame/src/frame/file/office/Engine.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Util.java" tooltip="frame/src/frame/util/Util.java"> +<persistable path="/frame/src/frame/util/Util.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="IOMappingItem.java" tooltip="frame/src/frame/file/office/IOMappingItem.java"> +<persistable path="/frame/src/frame/file/office/IOMappingItem.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Dispatcher.java" tooltip="frame/src/frame/server/Dispatcher.java"> +<persistable path="/frame/src/frame/server/Dispatcher.java"/> +</file> +<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="EnvelopWriter.java" tooltip="frame/src/frame/call/writer/EnvelopWriter.java"> +<persistable path="/frame/src/frame/call/writer/EnvelopWriter.java"/> +</file> <file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="EntityMeta.java" tooltip="frame/src/frame/data/meta/EntityMeta.java"> <persistable path="/frame/src/frame/data/meta/EntityMeta.java"/> </file> @@ -730,33 +855,6 @@ </file> <file factoryID="org.eclipse.jdt.ui.ClassFileEditorInputFactory" id="org.eclipse.jdt.ui.ClassFileEditor" name="Processor.class" tooltip="javax.annotation.processing.Processor"> <persistable org.eclipse.jdt.ui.ClassFileIdentifier="=framefile/D:\/jdk\/jre\/lib\/rt.jar<javax.annotation.processing(Processor.class"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Monitor.java" tooltip="framefile/src/frame/file/progressor/Monitor.java"> -<persistable path="/framefile/src/frame/file/progressor/Monitor.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Phase.java" tooltip="framefile/src/frame/file/progressor/Phase.java"> -<persistable path="/framefile/src/frame/file/progressor/Phase.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Progressor.java" tooltip="framefile/src/frame/file/Progressor.java"> -<persistable path="/framefile/src/frame/file/Progressor.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="IOProcessor.java" tooltip="framefile/src/frame/file/office/IOProcessor.java"> -<persistable path="/framefile/src/frame/file/office/IOProcessor.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="ExcelHandler.java" tooltip="framefile/src/frame/file/office/ExcelHandler.java"> -<persistable path="/framefile/src/frame/file/office/ExcelHandler.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="Engine.java" tooltip="framefile/src/frame/file/office/Engine.java"> -<persistable path="/framefile/src/frame/file/office/Engine.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="DataInvalidException.java" tooltip="framefile/src/frame/file/exception/DataInvalidException.java"> -<persistable path="/framefile/src/frame/file/exception/DataInvalidException.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="FileInvalidException.java" tooltip="framefile/src/frame/file/exception/FileInvalidException.java"> -<persistable path="/framefile/src/frame/file/exception/FileInvalidException.java"/> -</file> -<file factoryID="org.eclipse.ui.part.FileEditorInputFactory" id="org.eclipse.jdt.ui.CompilationUnitEditor" name="DataContext.java" tooltip="framefile/src/frame/file/DataContext.java"> -<persistable path="/framefile/src/frame/file/DataContext.java"/> </file> </mruList> </workbench> \ No newline at end of file diff --git a/source/my/.metadata/.plugins/org.eclipse.wst.jsdt.core/indexes/savedIndexNames.txt b/source/my/.metadata/.plugins/org.eclipse.wst.jsdt.core/indexes/savedIndexNames.txt index 0d3eb3d..75dc775 100644 --- a/source/my/.metadata/.plugins/org.eclipse.wst.jsdt.core/indexes/savedIndexNames.txt +++ b/source/my/.metadata/.plugins/org.eclipse.wst.jsdt.core/indexes/savedIndexNames.txt @@ -1,6 +1,6 @@ INDEX VERSION 1.122+D:\workspace\frame\source\my\.metadata\.plugins\org.eclipse.wst.jsdt.core\indexes -3887936429.index +417503767.index +3188200943.index 3109331711.index -1126096386.index -3509008705.index -1208877602.index +3034692854.index +2551459659.index diff --git a/source/my/.metadata/.plugins/org.eclipse.wst.validation/dep.index b/source/my/.metadata/.plugins/org.eclipse.wst.validation/dep.index index ab126e4..c68441d 100644 --- a/source/my/.metadata/.plugins/org.eclipse.wst.validation/dep.index +++ b/source/my/.metadata/.plugins/org.eclipse.wst.validation/dep.index Binary files differ diff --git a/source/my/.metadata/.plugins/org.tigris.subversion.subclipse.ui/dialog_settings.xml b/source/my/.metadata/.plugins/org.tigris.subversion.subclipse.ui/dialog_settings.xml index 63a71cf..98501da 100644 --- a/source/my/.metadata/.plugins/org.tigris.subversion.subclipse.ui/dialog_settings.xml +++ b/source/my/.metadata/.plugins/org.tigris.subversion.subclipse.ui/dialog_settings.xml @@ -16,15 +16,15 @@ <item value="768" key="DifferencesDialog.size.x"/> <item value="252" key="HistoryTableProvider.revisionsBlock.鏃ユ湡"/> <item value="248" key="DifferencesDialog.location.y"/> - <item value="503" key="HistoryTableProvider.revisionsBlock.娉ㄩ噴"/> - <item value="614" key="ResolveTreeConflict.location.x"/> <item value="500" key="CommitDialog.weights.0"/> + <item value="614" key="ResolveTreeConflict.location.x"/> + <item value="503" key="HistoryTableProvider.revisionsBlock.娉ㄩ噴"/> <item value="500" key="CommitDialog.weights.1"/> <item value="175" key="ResolveTreeConflict.location.y"/> - <item value="601" key="ConfigureTagsDialog.location.x"/> <item value="444" key="BranchTag.size.y"/> - <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn/project/straumann/straumann"/> + <item value="601" key="ConfigureTagsDialog.location.x"/> <item value="67" key="ConfigureTagsDialog.location.y"/> + <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn/project/straumann/straumann"/> <item value="687" key="MarkResolvedDialog.location.x"/> <item value="566" key="BranchTag.size.x"/> <item value="225" key="MarkResolvedDialog.location.y"/> @@ -49,22 +49,22 @@ <item value="http://139.196.106.178:9080/svn/project/cbi" key="UrlCombo.cbi.0"/> <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn"/> <item value="525" key="SetSvnPropertyDialog.size.x"/> - <item value="true" key="TreeConflictsView.container"/> <item value="75" key="TreeConflictsView.col.Resource"/> + <item value="true" key="TreeConflictsView.container"/> <item value="164" key="SetSvnPropertyDialog.location.y"/> <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn/project/cbi/cbi"/> - <item value="692" key="ResolveTreeConflict.size.x"/> <item value="http://139.196.106.178:9080/svn/project/straumann/straumann" key="UrlCombo.straumann.0"/> + <item value="692" key="ResolveTreeConflict.size.x"/> <item value="526" key="ResolveTreeConflict.size.y"/> <item value="252" key="HistoryTableProvider.MergeWizardUnblockRevisionsPage.鏃ユ湡"/> <item value="698" key="SetSvnPropertyDialog.location.x"/> - <item value="754" key="SwitchDialogWithConflictHandling.size.y"/> <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn/project/cbi"/> + <item value="754" key="SwitchDialogWithConflictHandling.size.y"/> <item value="606" key="SwitchDialogWithConflictHandling.size.x"/> - <item value="657" key="SwitchDialogWithConflictHandling.location.x"/> <item value="" key="DirectorySelectionPage.lastParent_http://139.196.106.178:9080/svn/project"/> - <item value="505" key="HistoryTableProvider.MergeWizardUnblockRevisionsPage.娉ㄩ噴"/> + <item value="657" key="SwitchDialogWithConflictHandling.location.x"/> <item value="23" key="SwitchDialogWithConflictHandling.location.y"/> + <item value="505" key="HistoryTableProvider.MergeWizardUnblockRevisionsPage.娉ㄩ噴"/> <item value="D:/workspace/workspace_myeclipse/activiti1.8/ttm" key="TreeConflictsView.resource"/> <item value="201" key="HistoryTableProvider.revisions.浣滆��"/> <item value="1186" key="CommitDialog.size.x"/> diff --git a/source/my/frame/.classpath b/source/my/frame/.classpath index c5aa531..d507a83 100644 --- a/source/my/frame/.classpath +++ b/source/my/frame/.classpath @@ -15,5 +15,8 @@ <classpathentry kind="lib" path="WebRoot/lib/poi-3.17.jar"/> <classpathentry kind="lib" path="WebRoot/lib/poi-ooxml-3.17.jar"/> <classpathentry kind="lib" path="WebRoot/lib/poi-ooxml-schemas-3.17.jar"/> + <classpathentry kind="lib" path="WebRoot/lib/commons-io-2.4.jar"/> + <classpathentry kind="lib" path="WebRoot/lib/portlet.jar"/> + <classpathentry kind="lib" path="WebRoot/lib/jacob.jar"/> <classpathentry kind="output" path="WebRoot/WEB-INF/classes"/> </classpath> diff --git a/source/my/frame/WebRoot/lib/commons-io-2.4.jar b/source/my/frame/WebRoot/lib/commons-io-2.4.jar new file mode 100644 index 0000000..90035a4 --- /dev/null +++ b/source/my/frame/WebRoot/lib/commons-io-2.4.jar Binary files differ diff --git a/source/my/frame/WebRoot/lib/jacob.jar b/source/my/frame/WebRoot/lib/jacob.jar new file mode 100644 index 0000000..c35ad12 --- /dev/null +++ b/source/my/frame/WebRoot/lib/jacob.jar Binary files differ diff --git a/source/my/frame/WebRoot/lib/portlet.jar b/source/my/frame/WebRoot/lib/portlet.jar new file mode 100644 index 0000000..7a80c30 --- /dev/null +++ b/source/my/frame/WebRoot/lib/portlet.jar Binary files differ diff --git a/source/my/frame/src/frame/file/ActivePeriod.java b/source/my/frame/src/frame/file/ActivePeriod.java new file mode 100644 index 0000000..679073d --- /dev/null +++ b/source/my/frame/src/frame/file/ActivePeriod.java @@ -0,0 +1,88 @@ +package frame.file; + +import java.util.ArrayList; +import java.util.List; + +import frame.expression.GlobalVariant; +import frame.expression.IVariantRequestListener; +import frame.expression.VariantExistsException; +import frame.expression.VariantRequestParams; + +public class ActivePeriod implements IVariantRequestListener { + + private static ActivePeriod instance; + private static Object lock = new Object(); + private String id; + private int year; + private int month; + private List<String> paramNames; + + private ActivePeriod() { + paramNames = new ArrayList<String>(); + } + + public static ActivePeriod getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new ActivePeriod(); + } + } + } + + return instance; + } + + public void init(String id, int year, int month) throws VariantExistsException { + ActivePeriod period = getInstance(); + + period.id = id; + period.year = year; + period.month = month; + + paramNames.add("year"); + paramNames.add("month"); + paramNames.add("year+1"); + GlobalVariant.regist(period); + } + + @Override + public List<String> getVariantNames() { + return paramNames; + } + + public String getStringValue(String name) { + if ("year".equals(name)) { + return String.valueOf(year); + } + else if ("year+1".equals(name)) { + return String.valueOf(year + 1); + } + else if ("month".equals(name)) { + return String.valueOf(month); + } + + return null; + } + + public String getId() { + return id; + } + + public int getYear() { + return year; + } + + public int getMonth() { + return month; + } + + //TODO params + @Override + public String getStringValue(String name, VariantRequestParams params) + throws Exception { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/source/my/frame/src/frame/file/ActivePeriodLoader.java b/source/my/frame/src/frame/file/ActivePeriodLoader.java new file mode 100644 index 0000000..1acdcbc --- /dev/null +++ b/source/my/frame/src/frame/file/ActivePeriodLoader.java @@ -0,0 +1,31 @@ +package frame.file; + +import frame.data.Entity; +import frame.data.EntitySet; +import frame.persist.NamedSQL; +import frame.persist.SQLRunner; + + +public class ActivePeriodLoader extends Preloader { + + @Override + public void load() throws Exception { + NamedSQL namedSQL = NamedSQL.getInstance("getDataSet"); + namedSQL.setTableName("workperiod"); + + EntitySet entitySet = SQLRunner.getEntitySet(namedSQL); + + if (entitySet.isEmpty()) { + throw new Exception("empty active period"); + } + + Entity entity = entitySet.next(); + + String id = entity.getString("id"); + int year = entity.getInt("year"); + int month = entity.getInt("month"); + + ActivePeriod.getInstance().init(id, year, month); + } + +} diff --git a/source/my/frame/src/frame/file/office/Engine.java b/source/my/frame/src/frame/file/office/Engine.java index b2268f8..4723787 100644 --- a/source/my/frame/src/frame/file/office/Engine.java +++ b/source/my/frame/src/frame/file/office/Engine.java @@ -26,7 +26,7 @@ private static Object locker = new Object(); private Logger logger; private ExcelLoader excelLoader; - + private Engine() { logger = LoggerFactory.getLogger(this.getClass()); excelLoader = new ExcelLoader(logger); diff --git a/source/my/frame/src/frame/file/office/IOMappingItem.java b/source/my/frame/src/frame/file/office/IOMappingItem.java index c360401..8d57929 100644 --- a/source/my/frame/src/frame/file/office/IOMappingItem.java +++ b/source/my/frame/src/frame/file/office/IOMappingItem.java @@ -32,7 +32,7 @@ return null; } - String[] values = Utils.split(exportType); + String[] values = Util.split(exportType); List<CellDataType> result = new ArrayList<CellDataType>(); for (String value : values) { diff --git a/source/my/frame/src/frame/file/office/excel/ExcelTranslator.java b/source/my/frame/src/frame/file/office/excel/ExcelTranslator.java new file mode 100644 index 0000000..7c00911 --- /dev/null +++ b/source/my/frame/src/frame/file/office/excel/ExcelTranslator.java @@ -0,0 +1,240 @@ +package frame.file.office.excel; + +import java.io.File; + +import org.apache.log4j.Logger; + +import com.jacob.activeX.ActiveXComponent; +import com.jacob.com.ComThread; +import com.jacob.com.Dispatch; +import com.jacob.com.Variant; + +public class ExcelTranslator { + + private static Logger logger; + + static { + logger = Logger.getLogger(ExcelTranslator.class); + } + + public synchronized static boolean testComActive() { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + xl.invoke("Quit", new Variant[] {}); + return true; + } + + public synchronized static void saveAs07(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAs03(File sourceFile, File targetFile) throws Exception { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Dispatch workbooks = null; Dispatch workbook = null; + try { + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(18) }, new int[1]); + + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + ex.printStackTrace(); + logger.error(ex.getMessage()); + } + } + } + catch (Exception e) { + logger.debug(e); + throw e; + } + finally { + ComThread.Release(); + } + } + + public synchronized static void saveAsXlsb(File sourceFile, File targetFile) { + ComThread.InitSTA(); + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + Dispatch workbooks = null; + Dispatch workbook = null; + + try { + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + // 涓嶆樉绀篍xcel + xl.setProperty("Visible", new Variant(false)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + //workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + //0--姝e父鎵撳紑锛� 1--淇宸ヤ綔绨匡紱 2--淇鏁版嵁 (涓嶈兘鐢ㄤ簬鎵撳紑07) + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); + + // 鍙︿繚瀛樹负Excel, 50-xlsb + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(50) }, new int[1]); + + } + catch (Exception e) { + logger.debug(e); + throw new RuntimeException(e); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + + ComThread.Release(); + } + } + + public static void main(String[] args) { + File sourceFile = new File("D:\\test\\prod.xlsx"); + File targetFile = new File("D:\\test\\test2.xlsx"); + + if (!sourceFile.exists()) { + System.out.println("file not exist:" + sourceFile); + return; + } + + if (targetFile.exists() && targetFile.canRead()) { + targetFile.delete(); + } + + ComThread.InitSTA(); + try { + ActiveXComponent xl = new ActiveXComponent("Excel.Application"); + try { + Object xlo = xl.getObject(); + Dispatch workbooks = null; Dispatch workbook = null; + + try { + // 涓嶆樉绀篍xcel + System.out.println("version=" + xl.getProperty("Version")); + System.out.println("version=" + Dispatch.get((Dispatch) xlo, "Version")); + xl.setProperty("Visible", new Variant(true)); + // 涓嶆彁绀鸿鍛婄瓑淇℃伅 + xl.setProperty("DisplayAlerts", new Variant(false)); + + workbooks = xl.getProperty("Workbooks").toDispatch(); + workbook = Dispatch.invoke(workbooks, "Open", Dispatch.Method, + new Object[] { sourceFile.getAbsolutePath(), + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, + Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, Variant.VariantNull, 1 + }, new int[1]).toDispatch(); +// workbook = Dispatch.call(workbooks, "Open", sourceFile.getAbsolutePath()).toDispatch(); + // 鍙︿繚瀛樹负Excel, 18-2003, 51-2007 + Dispatch.invoke(workbook, "SaveAs", Dispatch.Method, new Object[] { targetFile.getAbsolutePath(), new Variant(51) }, new int[1]); + System.err.println("ok!"); + } + finally { + try { + Dispatch.call((Dispatch) workbook, "Close", new Variant(false)); + } + catch (Exception ex) { + } + } + } + finally { + try { + xl.invoke("Quit", new Variant[] {}); + } + catch (Exception ex) { + } + } + } + catch (Exception e) { + System.out.println(e.getMessage()); + } + finally { + ComThread.Release(); + } + System.err.println("done!"); + } +} diff --git a/source/my/frame/src/frame/file/repositoty/Repository.java b/source/my/frame/src/frame/file/repositoty/Repository.java new file mode 100644 index 0000000..c612abf --- /dev/null +++ b/source/my/frame/src/frame/file/repositoty/Repository.java @@ -0,0 +1,190 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import frame.data.DataPool; +import frame.data.Entity; +import frame.expression.Expression; +import frame.expression.GlobalVariant; +import frame.expression.VariantContext; +import frame.expression.VariantRequestParams; +import frame.expression.VariantSegment; +import frame.file.UploadResult; +import frame.upload.FileItem; +import frame.util.Util; + + +public class Repository { + + private String name; + private String root; + private Expression pathRule; + private DataPool datapool; + + + public Repository(String name, String root) throws Exception { + this.name = name; + this.root = parsePath(root); + } + + public void setPath(String path) throws Exception { + pathRule = new Expression(path); + } + + public OutputStream getStream(String id) throws Exception { + Entity entity = DataHandler.getLine("filerepository", id); + + if (entity == null) { + throw new Exception("file not exists: " + id); + } + + String internalPath = entity.getString("path"); + String path = Util.joinPath(root, internalPath); + + File file = new File(path); + + if (!file.exists()) { + throw new Exception("file not exists: " + path); + } + + return new FileOutputStream(file); + } + + public String saveFileToAttachmentPath(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return path; + } + + public List<UploadResult> saveFile(List<FileItem> fileList, VariantRequestParams params) throws Exception { + List<UploadResult> result = new ArrayList<UploadResult>(); + + Expression expression = pathRule.newInstance(); + VariantContext context = new VariantContext(); + context.setParametersTo(expression, params); + + String internalPath = expression.getString(); + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + for (FileItem item: fileList) { + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + result.add(uploadResult); + } + + return result; + } + + public UploadResult saveFile(FileItem item) throws Exception { + //1. path + Expression expression = pathRule.newInstance(); + String internalPath = expression.toString(); + + String path = Util.joinPath(root, internalPath); + + File pathfile = new File(path); + if (!pathfile.exists()) { + pathfile.mkdirs(); + } + + String code = Util.newShortGUID(); + + UploadResult uploadResult = doSaveOneFile(path, internalPath, code, item); + + return uploadResult; + } + + private UploadResult doSaveOneFile(String path, String internalPath, String filecode, FileItem item) throws Exception { + String itemName = item.getName().substring(item.getName().lastIndexOf("\\") == -1 ? 0 : item.getName().lastIndexOf("\\") + 1); + + String internalFile = Util.joinPath(internalPath, itemName); + File file = new File(root, internalFile); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + item.write(file); + +/* Entity entity = new Entity("filerepository"); + entity.set("id", Util.newShortGUID()); + entity.set("typecode", "file"); + entity.set("filecode", filecode); + entity.set("path", internalFile); + entity.insert();*/ + + UploadResult result = new UploadResult(filecode); + //TODO uploadresult changed + + //result.setPath(path); + //result.setTempPath(path); + + //TODO event bus? + EventListener.fireRepositoryEvent("aftersave", result, datapool); + + return result; + } + + private String parsePath(String value) throws Exception { + Expression expression = new Expression(value); + + for (VariantSegment variant: expression) { + String name = variant.getName(); + int pos = value.indexOf("("); + + if (pos > 0) { + String realname = name.substring(0, pos); + String format = name.substring(pos + 1, name.length() - 1); + + VariantRequestParams params = new VariantRequestParams(); + params.addParam("format", format); + + GlobalVariant.getStringValue(realname, params); + } + else { + GlobalVariant.getStringValue(name, null); + } + } + + return expression.toString(); + } + + public String getName() { + return name; + } + + public String getRoot() { + return root; + } + +} diff --git a/source/my/frame/src/frame/file/repositoty/RepositoryContainer.java b/source/my/frame/src/frame/file/repositoty/RepositoryContainer.java new file mode 100644 index 0000000..5b2925e --- /dev/null +++ b/source/my/frame/src/frame/file/repositoty/RepositoryContainer.java @@ -0,0 +1,91 @@ +package frame.file.repositoty; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Iterator; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + +import frame.config.Configer; +import frame.util.Util; + + +public class RepositoryContainer extends PreloadContainer<Repository> { + + private static RepositoryContainer instance; + private Repository defaultRepository; + + public static synchronized RepositoryContainer getInstance() { + if (instance == null) { + instance = new RepositoryContainer(); + } + + return instance; + } + + @Override + public void load() throws Exception { + try { + File file = new File(Configer.getPath_Config(), "repository.xml"); + + logger.debug("load entity file:" + file); + InputStream inputStream = new FileInputStream(file); + + try { + SAXReader reader = new SAXReader(); + Document doc = reader.read(inputStream); + Element root = doc.getRootElement(); + + loadRepositorys(root); + + } catch (DocumentException e) { + logger.error("can not load sql file: " + file); + logger.error(e); + } finally { + try { + inputStream.close(); + } catch (IOException e) { + } + } + } + catch (Exception e) { + logger.error(e); + } + } + + private void loadRepositorys(Element root) throws Exception { + Iterator<?> iterator = root.elementIterator("repository"); + + while (iterator.hasNext()) { + Element element = (Element) iterator.next(); + loadOneRepository(element); + } + } + + private void loadOneRepository(Element element) throws Exception { + String name = element.attributeValue("name"); + String root = element.attributeValue("root"); + boolean isDefault = Util.stringToBoolean(element.attributeValue("default")); + + String path = element.getTextTrim(); + + Repository repository = new Repository(name, root); + repository.setPath(path); + + add(name, repository); + + if (isDefault) { + defaultRepository = repository; + } + } + + public Repository getDefault() { + return defaultRepository; + } + +} diff --git a/source/my/frame/src/frame/upload/DefaultFileItem.java b/source/my/frame/src/frame/upload/DefaultFileItem.java new file mode 100644 index 0000000..87685e3 --- /dev/null +++ b/source/my/frame/src/frame/upload/DefaultFileItem.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import frame.upload.disk.DiskFileItem; + + +/** + * <p> The default implementation of the + * {@link frame.upload.FileItem FileItem} interface. + * + * <p> After retrieving an instance of this class from a {@link + * frame.upload.DiskFileUpload DiskFileUpload} instance (see + * {@link frame.upload.DiskFileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@apache.org">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DefaultFileItem.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ +public class DefaultFileItem extends DiskFileItem { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs a new <code>DefaultFileItem</code> instance. + * + * @param fieldName The name of the form field. + * @param contentType The content type passed by the browser or + * <code>null</code> if not specified. + * @param isFormField Whether or not this item is a plain form field, as + * opposed to a file upload. + * @param fileName The original filename in the user's filesystem, or + * <code>null</code> if not specified. + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItem</code> instead. + */ + public DefaultFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + } + +} diff --git a/source/my/frame/src/frame/upload/DefaultFileItemFactory.java b/source/my/frame/src/frame/upload/DefaultFileItemFactory.java new file mode 100644 index 0000000..040e31f --- /dev/null +++ b/source/my/frame/src/frame/upload/DefaultFileItemFactory.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; + +import frame.upload.DefaultFileItem; +import frame.upload.FileItem; + +import frame.upload.disk.DiskFileItemFactory; + +/** + * <p>The default {@link frame.upload.FileItemFactory} + * implementation. This implementation creates + * {@link frame.upload.FileItem} instances which keep their + * content either in memory, for smaller items, or in a temporary file on disk, + * for larger items. The size threshold, above which content will be stored on + * disk, is configurable, as is the directory in which temporary files will be + * created.</p> + * + * <p>If not otherwise configured, the default configuration values are as + * follows: + * <ul> + * <li>Size threshold is 10KB.</li> + * <li>Repository is the system default temp directory, as returned by + * <code>System.getProperty("java.io.tmpdir")</code>.</li> + * </ul> + * </p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: DefaultFileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ +public class DefaultFileItemFactory extends DiskFileItemFactory { + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an unconfigured instance of this class. The resulting factory + * may be configured by calling the appropriate setter methods. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory() { + super(); + } + + + /** + * Constructs a preconfigured instance of this class. + * + * @param sizeThreshold The threshold, in bytes, below which items will be + * retained in memory and above which they will be + * stored as a file. + * @param repository The data repository, which is the directory in + * which files will be created, should the item size + * exceed the threshold. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public DefaultFileItemFactory(int sizeThreshold, File repository) { + super(sizeThreshold, repository); + } + + + // --------------------------------------------------------- Public Methods + + /** + * Create a new {@link frame.upload.DefaultFileItem} + * instance from the supplied parameters and the local factory + * configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ) { + return new DefaultFileItem(fieldName, contentType, + isFormField, fileName, getSizeThreshold(), getRepository()); + } + +} diff --git a/source/my/frame/src/frame/upload/DiskFileUpload.java b/source/my/frame/src/frame/upload/DiskFileUpload.java new file mode 100644 index 0000000..c9026cb --- /dev/null +++ b/source/my/frame/src/frame/upload/DiskFileUpload.java @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; +import java.util.List; +import javax.servlet.http.HttpServletRequest; + +import frame.upload.DefaultFileItemFactory; +import frame.upload.FileItemFactory; +import frame.upload.FileUploadBase; +import frame.upload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(HttpServletRequest)} to acquire a list of {@link + * frame.upload.FileItem}s associated with a given HTML + * widget.</p> + * + * <p>Individual parts will be stored in temporary disk storage or in memory, + * depending on their size, and will be available as {@link + * frame.upload.FileItem}s.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: DiskFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + * + * @deprecated Use <code>ServletFileUpload</code> together with + * <code>DiskFileItemFactory</code> instead. + */ +public class DiskFileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private DefaultFileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an instance of this class which uses the default factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload(DefaultFileItemFactory fileItemFactory) + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload() { + super(); + this.fileItemFactory = new DefaultFileItemFactory(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #DiskFileUpload() + * @param fileItemFactory The file item factory to use. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public DiskFileUpload(DefaultFileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. The factory must + * be an instance of <code>DefaultFileItemFactory</code> or a subclass + * thereof, or else a <code>ClassCastException</code> will be thrown. + * + * @param factory The factory class for new file items. + * + * @deprecated Use <code>FileUpload</code> instead. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = (DefaultFileItemFactory) factory; + } + + + /** + * Returns the size threshold beyond which files are written directly to + * disk. + * + * @return The size threshold, in bytes. + * + * @see #setSizeThreshold(int) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public int getSizeThreshold() { + return fileItemFactory.getSizeThreshold(); + } + + + /** + * Sets the size threshold beyond which files are written directly to disk. + * + * @param sizeThreshold The size threshold, in bytes. + * + * @see #getSizeThreshold() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setSizeThreshold(int sizeThreshold) { + fileItemFactory.setSizeThreshold(sizeThreshold); + } + + + /** + * Returns the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @return The path to the temporary file location. + * + * @see #setRepositoryPath(String) + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public String getRepositoryPath() { + return fileItemFactory.getRepository().getPath(); + } + + + /** + * Sets the location used to temporarily store files that are larger + * than the configured size threshold. + * + * @param repositoryPath The path to the temporary file location. + * + * @see #getRepositoryPath() + * + * @deprecated Use <code>DiskFileItemFactory</code> instead. + */ + public void setRepositoryPath(String repositoryPath) { + fileItemFactory.setRepository(new File(repositoryPath)); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. If files are stored + * on disk, the path is given by <code>getRepository()</code>. + * + * @param req The servlet request to be parsed. Must be non-null. + * @param sizeThreshold The max size in bytes to be stored in memory. + * @param sizeMax The maximum allowed upload size, in bytes. + * @param path The location where the files should be stored. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @deprecated Use <code>ServletFileUpload</code> instead. + */ + public List /* FileItem */ parseRequest(HttpServletRequest req, + int sizeThreshold, + long sizeMax, String path) + throws FileUploadException { + setSizeThreshold(sizeThreshold); + setSizeMax(sizeMax); + setRepositoryPath(path); + return parseRequest(req); + } + +} diff --git a/source/my/frame/src/frame/upload/FileItem.java b/source/my/frame/src/frame/upload/FileItem.java new file mode 100644 index 0000000..2975366 --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItem.java @@ -0,0 +1,229 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; + +import frame.upload.InvalidFileNameException; + +/** + * <p> This class represents a file or form item that was received within a + * <code>multipart/form-data</code> POST request. + * + * <p> After retrieving an instance of this class from a {@link + * frame.upload.FileUpload FileUpload} instance (see + * {@link frame.upload.FileUpload + * #parseRequest(javax.servlet.http.HttpServletRequest)}), you may + * either request all contents of the file at once using {@link #get()} or + * request an {@link java.io.InputStream InputStream} with + * {@link #getInputStream()} and process the file without attempting to load + * it into memory, which may come handy with large files. + * + * <p> While this interface does not extend + * <code>javax.activation.DataSource</code> per se (to avoid a seldom used + * dependency), several of the defined methods are specifically defined with + * the same signatures as methods in that interface. This allows an + * implementation of this interface to also implement + * <code>javax.activation.DataSource</code> with minimal additional work. + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:sean@informage.net">Sean Legassick</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItem.java 963609 2010-07-13 06:56:47Z jochen $ + */ +public interface FileItem extends Serializable { + + + // ------------------------------- Methods from javax.activation.DataSource + + + /** + * Returns an {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @return An {@link java.io.InputStream InputStream} that can be + * used to retrieve the contents of the file. + * + * @throws IOException if an error occurs. + */ + InputStream getInputStream() throws IOException; + + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + * @throws InvalidFileNameException The file name contains a NUL character, + * which might be an indicator of a security attack. If you intend to + * use the file name anyways, catch the exception and use + * InvalidFileNameException#getName(). + */ + String getName(); + + + // ------------------------------------------------------- FileItem methods + + + /** + * Provides a hint as to whether or not the file contents will be read + * from memory. + * + * @return <code>true</code> if the file contents will be read from memory; + * <code>false</code> otherwise. + */ + boolean isInMemory(); + + + /** + * Returns the size of the file item. + * + * @return The size of the file item, in bytes. + */ + long getSize(); + + + /** + * Returns the contents of the file item as an array of bytes. + * + * @return The contents of the file item as an array of bytes. + */ + byte[] get(); + + + /** + * Returns the contents of the file item as a String, using the specified + * encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @param encoding The character encoding to use. + * + * @return The contents of the item, as a string. + * + * @throws UnsupportedEncodingException if the requested character + * encoding is not available. + */ + String getString(String encoding) throws UnsupportedEncodingException; + + + /** + * Returns the contents of the file item as a String, using the default + * character encoding. This method uses {@link #get()} to retrieve the + * contents of the item. + * + * @return The contents of the item, as a string. + */ + String getString(); + + + /** + * A convenience method to write an uploaded item to disk. The client code + * is not concerned with whether or not the item is stored in memory, or on + * disk in a temporary location. They just want to write the uploaded item + * to a file. + * <p> + * This method is not guaranteed to succeed if called more than once for + * the same item. This allows a particular implementation to use, for + * example, file renaming, where possible, rather than copying all of the + * underlying data, thus gaining a significant performance benefit. + * + * @param file The <code>File</code> into which the uploaded item should + * be stored. + * + * @throws Exception if an error occurs. + */ + void write(File file) throws Exception; + + + /** + * Deletes the underlying storage for a file item, including deleting any + * associated temporary disk file. Although this storage will be deleted + * automatically when the <code>FileItem</code> instance is garbage + * collected, this method can be used to ensure that this is done at an + * earlier time, thus preserving system resources. + */ + void delete(); + + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + + /** + * Sets the field name used to reference this file item. + * + * @param name The name of the form field. + */ + void setFieldName(String name); + + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); + + + /** + * Specifies whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @param state <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + void setFormField(boolean state); + + + /** + * Returns an {@link java.io.OutputStream OutputStream} that can + * be used for storing the contents of the file. + * + * @return An {@link java.io.OutputStream OutputStream} that can be used + * for storing the contensts of the file. + * + * @throws IOException if an error occurs. + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/source/my/frame/src/frame/upload/FileItemFactory.java b/source/my/frame/src/frame/upload/FileItemFactory.java new file mode 100644 index 0000000..3acdf1f --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItemFactory.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import frame.upload.FileItem; + + +/** + * <p>A factory interface for creating {@link FileItem} instances. Factories + * can provide their own custom configuration, over and above that provided + * by the default file upload implementation.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @version $Id: FileItemFactory.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface FileItemFactory { + + /** + * Create a new {@link FileItem} instance from the supplied parameters and + * any local factory configuration. + * + * @param fieldName The name of the form field. + * @param contentType The content type of the form field. + * @param isFormField <code>true</code> if this is a plain form field; + * <code>false</code> otherwise. + * @param fileName The name of the uploaded file, if any, as supplied + * by the browser or other client. + * + * @return The newly created file item. + */ + FileItem createItem( + String fieldName, + String contentType, + boolean isFormField, + String fileName + ); +} diff --git a/source/my/frame/src/frame/upload/FileItemHeaders.java b/source/my/frame/src/frame/upload/FileItemHeaders.java new file mode 100644 index 0000000..1a6a1f7 --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItemHeaders.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.util.Iterator; + +/** + * <p> This class provides support for accessing the headers for a file or form + * item that was received within a <code>multipart/form-data</code> POST + * request.</p> + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public interface FileItemHeaders { + /** + * Returns the value of the specified part header as a <code>String</code>. + * If the part did not include a header of the specified name, this method + * return <code>null</code>. If there are multiple headers with the same + * name, this method returns the first header in the item. The header + * name is case insensitive. + * + * @param name a <code>String</code> specifying the header name + * @return a <code>String</code> containing the value of the requested + * header, or <code>null</code> if the item does not have a header + * of that name + */ + String getHeader(String name); + + /** + * <p> + * Returns all the values of the specified item header as an + * <code>Enumeration</code> of <code>String</code> objects. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @param name a <code>String</code> specifying the header name + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name, return an empty <code>Enumeration</code> + */ + Iterator getHeaders(String name); + + /** + * <p> + * Returns an <code>Enumeration</code> of all the header names. + * </p> + * <p> + * If the item did not include any headers of the specified name, this + * method returns an empty <code>Enumeration</code>. The header name is + * case insensitive. + * </p> + * + * @return an <code>Enumeration</code> containing the values of the + * requested header. If the item does not have any headers of + * that name return an empty <code>Enumeration</code> + */ + Iterator getHeaderNames(); +} diff --git a/source/my/frame/src/frame/upload/FileItemHeadersSupport.java b/source/my/frame/src/frame/upload/FileItemHeadersSupport.java new file mode 100644 index 0000000..360b9f7 --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItemHeadersSupport.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import frame.upload.FileItem; +import frame.upload.FileItemHeaders; +import frame.upload.FileItemStream; + +/** + * Interface that will indicate that {@link FileItem} or {@link FileItemStream} + * implementations will accept the headers read for the item. + * + * @author Michael C. Macaluso + * @since 1.3 + * + * @see FileItem + * @see FileItemStream + */ +public interface FileItemHeadersSupport { + /** + * Returns the collection of headers defined locally within this item. + * + * @return the {@link FileItemHeaders} present for this item. + */ + FileItemHeaders getHeaders(); + + /** + * Sets the headers read from within an item. Implementations of + * {@link FileItem} or {@link FileItemStream} should implement this + * interface to be able to get the raw headers found within the item + * header block. + * + * @param headers the instance that holds onto the headers + * for this instance. + */ + void setHeaders(FileItemHeaders headers); +} diff --git a/source/my/frame/src/frame/upload/FileItemIterator.java b/source/my/frame/src/frame/upload/FileItemIterator.java new file mode 100644 index 0000000..6fa985f --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItemIterator.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; +import java.io.IOException; + +import frame.upload.FileItemStream; +import frame.upload.FileUploadBase; +import frame.upload.FileUploadException; +import frame.upload.RequestContext; + + +/** + * An iterator, as returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}. + */ +public interface FileItemIterator { + /** + * Returns, whether another instance of {@link FileItemStream} + * is available. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return True, if one or more additional file items + * are available, otherwise false. + */ + boolean hasNext() throws FileUploadException, IOException; + + /** + * Returns the next available {@link FileItemStream}. + * @throws java.util.NoSuchElementException No more items are available. Use + * {@link #hasNext()} to prevent this exception. + * @throws FileUploadException Parsing or processing the + * file item failed. + * @throws IOException Reading the file item failed. + * @return FileItemStream instance, which provides + * access to the next file item. + */ + FileItemStream next() throws FileUploadException, IOException; +} diff --git a/source/my/frame/src/frame/upload/FileItemStream.java b/source/my/frame/src/frame/upload/FileItemStream.java new file mode 100644 index 0000000..2cdecb8 --- /dev/null +++ b/source/my/frame/src/frame/upload/FileItemStream.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.IOException; +import java.io.InputStream; + +import frame.upload.FileItemHeadersSupport; +import frame.upload.FileItemStream; +import frame.upload.FileUploadBase; +import frame.upload.RequestContext; + + +/** + * <p> This interface provides access to a file or form item that was + * received within a <code>multipart/form-data</code> POST request. + * The items contents are retrieved by calling {@link #openStream()}.</p> + * <p>Instances of this class are created by accessing the + * iterator, returned by + * {@link FileUploadBase#getItemIterator(RequestContext)}.</p> + * <p><em>Note</em>: There is an interaction between the iterator and + * its associated instances of {@link FileItemStream}: By invoking + * {@link java.util.Iterator#hasNext()} on the iterator, you discard all data, + * which hasn't been read so far from the previous data.</p> + */ +public interface FileItemStream extends FileItemHeadersSupport { + /** + * This exception is thrown, if an attempt is made to read + * data from the {@link InputStream}, which has been returned + * by {@link FileItemStream#openStream()}, after + * {@link java.util.Iterator#hasNext()} has been invoked on the + * iterator, which created the {@link FileItemStream}. + */ + public static class ItemSkippedException extends IOException { + /** + * The exceptions serial version UID, which is being used + * when serializing an exception instance. + */ + private static final long serialVersionUID = -7280778431581963740L; + } + + /** Creates an {@link InputStream}, which allows to read the + * items contents. + * @return The input stream, from which the items data may + * be read. + * @throws IllegalStateException The method was already invoked on + * this item. It is not possible to recreate the data stream. + * @throws IOException An I/O error occurred. + * @see ItemSkippedException + */ + InputStream openStream() throws IOException; + + /** + * Returns the content type passed by the browser or <code>null</code> if + * not defined. + * + * @return The content type passed by the browser or <code>null</code> if + * not defined. + */ + String getContentType(); + + /** + * Returns the original filename in the client's filesystem, as provided by + * the browser (or other client software). In most cases, this will be the + * base file name, without path information. However, some clients, such as + * the Opera browser, do include path information. + * + * @return The original filename in the client's filesystem. + */ + String getName(); + + /** + * Returns the name of the field in the multipart form corresponding to + * this file item. + * + * @return The name of the form field. + */ + String getFieldName(); + + /** + * Determines whether or not a <code>FileItem</code> instance represents + * a simple form field. + * + * @return <code>true</code> if the instance represents a simple form + * field; <code>false</code> if it represents an uploaded file. + */ + boolean isFormField(); +} diff --git a/source/my/frame/src/frame/upload/FileUpload.java b/source/my/frame/src/frame/upload/FileUpload.java new file mode 100644 index 0000000..22a8d7a --- /dev/null +++ b/source/my/frame/src/frame/upload/FileUpload.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import frame.upload.FileItemFactory; +import frame.upload.FileUploadBase; + + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link frame.upload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: FileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class FileUpload + extends FileUploadBase { + + // ----------------------------------------------------------- Data members + + + /** + * The factory to use to create new form items. + */ + private FileItemFactory fileItemFactory; + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see #FileUpload(FileItemFactory) + */ + public FileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see #FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public FileUpload(FileItemFactory fileItemFactory) { + super(); + this.fileItemFactory = fileItemFactory; + } + + + // ----------------------------------------------------- Property accessors + + + /** + * Returns the factory class used when creating file items. + * + * @return The factory class for new file items. + */ + public FileItemFactory getFileItemFactory() { + return fileItemFactory; + } + + + /** + * Sets the factory class to use when creating file items. + * + * @param factory The factory class for new file items. + */ + public void setFileItemFactory(FileItemFactory factory) { + this.fileItemFactory = factory; + } + + +} diff --git a/source/my/frame/src/frame/upload/FileUploadBase.java b/source/my/frame/src/frame/upload/FileUploadBase.java new file mode 100644 index 0000000..273d226 --- /dev/null +++ b/source/my/frame/src/frame/upload/FileUploadBase.java @@ -0,0 +1,675 @@ +package frame.upload; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.servlet.http.HttpServletRequest; + +import frame.upload.MultipartStream.ItemInputStream; +import frame.upload.servlet.ServletFileUpload; +import frame.upload.servlet.ServletRequestContext; +import frame.upload.util.Closeable; +import frame.upload.util.FileItemHeadersImpl; +import frame.upload.util.LimitedInputStream; +import frame.upload.util.Streams; + + +public abstract class FileUploadBase { + + public static final boolean isMultipartContent(RequestContext ctx) { + String contentType = ctx.getContentType(); + + if (contentType == null) { + return false; + } + + if (contentType.toLowerCase().startsWith(MULTIPART)) { + return true; + } + return false; + } + + public static boolean isMultipartContent(HttpServletRequest req) { + return ServletFileUpload.isMultipartContent(req); + } + + public static final String CONTENT_TYPE = "Content-type"; + public static final String CONTENT_DISPOSITION = "Content-disposition"; + public static final String CONTENT_LENGTH = "Content-length"; + public static final String FORM_DATA = "form-data"; + public static final String ATTACHMENT = "attachment"; + public static final String MULTIPART = "multipart/"; + public static final String MULTIPART_FORM_DATA = "multipart/form-data"; + public static final String MULTIPART_MIXED = "multipart/mixed"; + public static final int MAX_HEADER_SIZE = 1024; + + private long sizeMax = -1; + private long fileSizeMax = -1; + private String headerEncoding; + private ProgressListener listener; + + public abstract FileItemFactory getFileItemFactory(); + public abstract void setFileItemFactory(FileItemFactory factory); + + public long getSizeMax() { + return sizeMax; + } + + public void setSizeMax(long sizeMax) { + this.sizeMax = sizeMax; + } + + public long getFileSizeMax() { + return fileSizeMax; + } + + public void setFileSizeMax(long fileSizeMax) { + this.fileSizeMax = fileSizeMax; + } + + public String getHeaderEncoding() { + return headerEncoding; + } + + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + public List parseRequest(HttpServletRequest req) throws FileUploadException { + return parseRequest(new ServletRequestContext(req)); + } + + public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { + return new FileItemIteratorImpl(ctx); + } + + public List parseRequest(RequestContext ctx) throws FileUploadException { + List items = new ArrayList(); + boolean successful = false; + + try { + FileItemIterator iter = getItemIterator(ctx); + FileItemFactory fac = getFileItemFactory(); + + if (fac == null) { + throw new NullPointerException("No FileItemFactory has been set."); + } + + while (iter.hasNext()) { + final FileItemStream item = iter.next(); + final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), item.isFormField(), fileName); + items.add(fileItem); + try { + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new IOFileUploadException("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage(), e); + } + + if (fileItem instanceof FileItemHeadersSupport) { + final FileItemHeaders fih = item.getHeaders(); + ((FileItemHeadersSupport) fileItem).setHeaders(fih); + } + } + successful = true; + return items; + } + catch (FileUploadIOException e) { + throw (FileUploadException) e.getCause(); + } + catch (IOException e) { + throw new FileUploadException(e.getMessage(), e); + } + finally { + if (!successful) { + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + FileItem fileItem = (FileItem) iterator.next(); + try { + fileItem.delete(); + } catch (Throwable e) { + } + } + } + } + } + + protected byte[] getBoundary(String contentType) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(contentType, new char[] {';', ','}); + String boundaryStr = (String) params.get("boundary"); + + if (boundaryStr == null) { + return null; + } + byte[] boundary; + try { + boundary = boundaryStr.getBytes("ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + boundary = boundaryStr.getBytes(); + } + return boundary; + } + + + protected String getFileName(Map /* String, String */ headers) { + return getFileName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected String getFileName(FileItemHeaders headers) { + return getFileName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFileName(String pContentDisposition) { + String fileName = null; + if (pContentDisposition != null) { + String cdl = pContentDisposition.toLowerCase(); + if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + if (params.containsKey("filename")) { + fileName = (String) params.get("filename"); + if (fileName != null) { + fileName = fileName.trim(); + } else { + // Even if there is no value, the parameter is present, + // so we return an empty file name rather than no file + // name. + fileName = ""; + } + } + } + } + return fileName; + } + + + protected String getFieldName(FileItemHeaders headers) { + return getFieldName(headers.getHeader(CONTENT_DISPOSITION)); + } + + private String getFieldName(String pContentDisposition) { + String fieldName = null; + if (pContentDisposition != null && pContentDisposition.toLowerCase().startsWith(FORM_DATA)) { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + // Parameter parser can handle null input + Map params = parser.parse(pContentDisposition, ';'); + fieldName = (String) params.get("name"); + if (fieldName != null) { + fieldName = fieldName.trim(); + } + } + return fieldName; + } + + protected String getFieldName(Map /* String, String */ headers) { + return getFieldName(getHeader(headers, CONTENT_DISPOSITION)); + } + + protected FileItem createItem(Map /* String, String */ headers, boolean isFormField) + throws FileUploadException { + return getFileItemFactory().createItem(getFieldName(headers), + getHeader(headers, CONTENT_TYPE), + isFormField, + getFileName(headers)); + } + + protected FileItemHeaders getParsedHeaders(String headerPart) { + final int len = headerPart.length(); + FileItemHeadersImpl headers = newFileItemHeaders(); + int start = 0; + for (;;) { + int end = parseEndOfLine(headerPart, start); + if (start == end) { + break; + } + String header = headerPart.substring(start, end); + start = end + 2; + while (start < len) { + int nonWs = start; + while (nonWs < len) { + char c = headerPart.charAt(nonWs); + if (c != ' ' && c != '\t') { + break; + } + ++nonWs; + } + if (nonWs == start) { + break; + } + // Continuation line found + end = parseEndOfLine(headerPart, nonWs); + header += " " + headerPart.substring(nonWs, end); + start = end + 2; + } + parseHeaderLine(headers, header); + } + return headers; + } + + protected FileItemHeadersImpl newFileItemHeaders() { + return new FileItemHeadersImpl(); + } + + protected Map /* String, String */ parseHeaders(String headerPart) { + FileItemHeaders headers = getParsedHeaders(headerPart); + Map result = new HashMap(); + for (Iterator iter = headers.getHeaderNames(); iter.hasNext();) { + String headerName = (String) iter.next(); + Iterator iter2 = headers.getHeaders(headerName); + String headerValue = (String) iter2.next(); + while (iter2.hasNext()) { + headerValue += "," + iter2.next(); + } + result.put(headerName, headerValue); + } + return result; + } + + private int parseEndOfLine(String headerPart, int end) { + int index = end; + for (;;) { + int offset = headerPart.indexOf('\r', index); + if (offset == -1 || offset + 1 >= headerPart.length()) { + throw new IllegalStateException( + "Expected headers to be terminated by an empty line."); + } + if (headerPart.charAt(offset + 1) == '\n') { + return offset; + } + index = offset + 1; + } + } + + private void parseHeaderLine(FileItemHeadersImpl headers, String header) { + final int colonOffset = header.indexOf(':'); + if (colonOffset == -1) { + // This header line is malformed, skip it. + return; + } + String headerName = header.substring(0, colonOffset).trim(); + String headerValue = + header.substring(header.indexOf(':') + 1).trim(); + headers.addHeader(headerName, headerValue); + } + + protected final String getHeader(Map /* String, String */ headers, String name) { + return (String) headers.get(name.toLowerCase()); + } + + private class FileItemIteratorImpl implements FileItemIterator { + + class FileItemStreamImpl implements FileItemStream { + private final String contentType; + private final String fieldName; + private final String name; + private final boolean formField; + private final InputStream stream; + private boolean opened; + private FileItemHeaders headers; + + FileItemStreamImpl(String pName, String pFieldName, String pContentType, boolean pFormField, long pContentLength) throws IOException { + name = pName; + fieldName = pFieldName; + contentType = pContentType; + formField = pFormField; + final ItemInputStream itemStream = multi.newInputStream(); + InputStream istream = itemStream; + if (fileSizeMax != -1) { + if (pContentLength != -1 + && pContentLength > fileSizeMax) { + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + fileSizeMax + + " bytes.", + pContentLength, fileSizeMax); + e.setFileName(pName); + e.setFieldName(pFieldName); + throw new FileUploadIOException(e); + } + istream = new LimitedInputStream(istream, fileSizeMax) { + protected void raiseError(long pSizeMax, long pCount) + throws IOException { + itemStream.close(true); + FileSizeLimitExceededException e = + new FileSizeLimitExceededException( + "The field " + fieldName + + " exceeds its maximum permitted " + + " size of " + pSizeMax + + " bytes.", + pCount, pSizeMax); + e.setFieldName(fieldName); + e.setFileName(name); + throw new FileUploadIOException(e); + } + }; + } + stream = istream; + } + + public String getContentType() { + return contentType; + } + + public String getFieldName() { + return fieldName; + } + + public String getName() { + return Streams.checkFileName(name); + } + + public boolean isFormField() { + return formField; + } + + public InputStream openStream() throws IOException { + if (opened) { + throw new IllegalStateException("The stream was already opened."); + } + if (((Closeable) stream).isClosed()) { + throw new FileItemStream.ItemSkippedException(); + } + return stream; + } + + void close() throws IOException { + stream.close(); + } + + public FileItemHeaders getHeaders() { + return headers; + } + + @Override + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } + } + + private final MultipartStream multi; + private final MultipartStream.ProgressNotifier notifier; + private final byte[] boundary; + private FileItemStreamImpl currentItem; + private String currentFieldName; + private boolean skipPreamble; + private boolean itemValid; + private boolean eof; + + FileItemIteratorImpl(RequestContext ctx) throws FileUploadException, IOException { + if (ctx == null) { + throw new NullPointerException("ctx parameter"); + } + + String contentType = ctx.getContentType(); + if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) { + throw new InvalidContentTypeException( + "the request doesn't contain a " + MULTIPART_FORM_DATA + " or " + MULTIPART_MIXED + " stream, content type header is " + contentType); + } + + InputStream input = ctx.getInputStream(); + + if (sizeMax >= 0) { + int requestSize = ctx.getContentLength(); + if (requestSize == -1) { + input = new LimitedInputStream(input, sizeMax) { + protected void raiseError(long pSizeMax, long pCount) throws IOException { + FileUploadException ex = new SizeLimitExceededException("the request was rejected because" + " its size (" + pCount + ") exceeds the configured maximum" + " (" + pSizeMax + ")", pCount, pSizeMax); + throw new FileUploadIOException(ex); + } + }; + } else { + if (sizeMax >= 0 && requestSize > sizeMax) { + throw new SizeLimitExceededException("the request was rejected because its size (" + requestSize + ") exceeds the configured maximum (" + sizeMax + ")", requestSize, sizeMax); + } + } + } + + String charEncoding = headerEncoding; + if (charEncoding == null) { + charEncoding = ctx.getCharacterEncoding(); + } + + boundary = getBoundary(contentType); + if (boundary == null) { + throw new FileUploadException("the request was rejected because " + "no multipart boundary was found"); + } + + notifier = new MultipartStream.ProgressNotifier(listener, ctx.getContentLength()); + multi = new MultipartStream(input, boundary, notifier); + multi.setHeaderEncoding(charEncoding); + + skipPreamble = true; + findNextItem(); + } + + private boolean findNextItem() throws IOException { + if (eof) { + return false; + } + + if (currentItem != null) { + currentItem.close(); + currentItem = null; + } + + for (;;) { + boolean nextPart; + if (skipPreamble) { + nextPart = multi.skipPreamble(); + } else { + nextPart = multi.readBoundary(); + } + + if (!nextPart) { + if (currentFieldName == null) { + // Outer multipart terminated -> No more data + eof = true; + return false; + } + // Inner multipart terminated -> Return to parsing the outer + multi.setBoundary(boundary); + currentFieldName = null; + continue; + } + + FileItemHeaders headers = getParsedHeaders(multi.readHeaders()); + if (currentFieldName == null) { + // We're parsing the outer multipart + String fieldName = getFieldName(headers); + if (fieldName != null) { + String subContentType = headers.getHeader(CONTENT_TYPE); + if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) { + currentFieldName = fieldName; + // Multiple files associated with this field name + byte[] subBoundary = getBoundary(subContentType); + multi.setBoundary(subBoundary); + skipPreamble = true; + continue; + } + String fileName = getFileName(headers); + currentItem = new FileItemStreamImpl(fileName, fieldName, headers.getHeader(CONTENT_TYPE), fileName == null, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } else { + String fileName = getFileName(headers); + if (fileName != null) { + currentItem = new FileItemStreamImpl(fileName, currentFieldName, headers.getHeader(CONTENT_TYPE), false, getContentLength(headers)); + notifier.noteItem(); + itemValid = true; + return true; + } + } + multi.discardBodyData(); + } + } + + private long getContentLength(FileItemHeaders pHeaders) { + try { + return Long.parseLong(pHeaders.getHeader(CONTENT_LENGTH)); + } catch (Exception e) { + return -1; + } + } + + public boolean hasNext() throws FileUploadException, IOException { + if (eof) { + return false; + } + if (itemValid) { + return true; + } + return findNextItem(); + } + + public FileItemStream next() throws FileUploadException, IOException { + if (eof || (!itemValid && !hasNext())) { + throw new NoSuchElementException(); + } + itemValid = false; + return currentItem; + } + } + + public static class FileUploadIOException extends IOException { + private static final long serialVersionUID = -7047616958165584154L; + private final FileUploadException cause; + + public FileUploadIOException(FileUploadException pCause) { + cause = pCause; + } + + public Throwable getCause() { + return cause; + } + } + + public static class InvalidContentTypeException extends FileUploadException { + private static final long serialVersionUID = -9073026332015646668L; + + public InvalidContentTypeException() { + // Nothing to do. + } + + public InvalidContentTypeException(String message) { + super(message); + } + } + + public static class IOFileUploadException extends FileUploadException { + private static final long serialVersionUID = 1749796615868477269L; + private final IOException cause; + + public IOFileUploadException(String pMsg, IOException pException) { + super(pMsg); + cause = pException; + } + + public Throwable getCause() { + return cause; + } + } + + protected abstract static class SizeException extends FileUploadException { + private static final long serialVersionUID = -8776225574705254126L; + private final long actual; + private final long permitted; + + protected SizeException(String message, long actual, long permitted) { + super(message); + this.actual = actual; + this.permitted = permitted; + } + + public long getActualSize() { + return actual; + } + + public long getPermittedSize() { + return permitted; + } + } + + public static class UnknownSizeException + extends FileUploadException { + private static final long serialVersionUID = 7062279004812015273L; + + public UnknownSizeException() { + super(); + } + + public UnknownSizeException(String message) { + super(message); + } + } + + public static class SizeLimitExceededException extends SizeException { + private static final long serialVersionUID = -2474893167098052828L; + + public SizeLimitExceededException() { + this(null, 0, 0); + } + + public SizeLimitExceededException(String message) { + this(message, 0, 0); + } + + public SizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + } + + public static class FileSizeLimitExceededException extends SizeException { + private static final long serialVersionUID = 8150776562029630058L; + + private String fileName; + private String fieldName; + + public FileSizeLimitExceededException(String message, long actual, long permitted) { + super(message, actual, permitted); + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String pFileName) { + fileName = pFileName; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String pFieldName) { + fieldName = pFieldName; + } + } + + public ProgressListener getProgressListener() { + return listener; + } + + public void setProgressListener(ProgressListener pListener) { + listener = pListener; + } +} diff --git a/source/my/frame/src/frame/upload/FileUploadException.java b/source/my/frame/src/frame/upload/FileUploadException.java new file mode 100644 index 0000000..e40cacb --- /dev/null +++ b/source/my/frame/src/frame/upload/FileUploadException.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.PrintStream; +import java.io.PrintWriter; + + +/** + * Exception for errors encountered while processing the request. + * + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @version $Id: FileUploadException.java 551000 2007-06-27 00:59:16Z jochen $ + */ +public class FileUploadException extends Exception { + /** + * Serial version UID, being used, if the exception + * is serialized. + */ + private static final long serialVersionUID = 8881893724388807504L; + /** + * The exceptions cause. We overwrite the cause of + * the super class, which isn't available in Java 1.3. + */ + private final Throwable cause; + + /** + * Constructs a new <code>FileUploadException</code> without message. + */ + public FileUploadException() { + this(null, null); + } + + /** + * Constructs a new <code>FileUploadException</code> with specified detail + * message. + * + * @param msg the error message. + */ + public FileUploadException(final String msg) { + this(msg, null); + } + + /** + * Creates a new <code>FileUploadException</code> with the given + * detail message and cause. + * @param msg The exceptions detail message. + * @param cause The exceptions cause. + */ + public FileUploadException(String msg, Throwable cause) { + super(msg); + this.cause = cause; + } + + /** + * Prints this throwable and its backtrace to the specified print stream. + * + * @param stream <code>PrintStream</code> to use for output + */ + public void printStackTrace(PrintStream stream) { + super.printStackTrace(stream); + if (cause != null) { + stream.println("Caused by:"); + cause.printStackTrace(stream); + } + } + + /** + * Prints this throwable and its backtrace to the specified + * print writer. + * + * @param writer <code>PrintWriter</code> to use for output + */ + public void printStackTrace(PrintWriter writer) { + super.printStackTrace(writer); + if (cause != null) { + writer.println("Caused by:"); + cause.printStackTrace(writer); + } + } + + public Throwable getCause() { + return cause; + } +} diff --git a/source/my/frame/src/frame/upload/InvalidFileNameException.java b/source/my/frame/src/frame/upload/InvalidFileNameException.java new file mode 100644 index 0000000..ec01380 --- /dev/null +++ b/source/my/frame/src/frame/upload/InvalidFileNameException.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + + +/** + * This exception is thrown in case of an invalid file name. + * A file name is invalid, if it contains a NUL character. + * Attackers might use this to circumvent security checks: + * For example, a malicious user might upload a file with the name + * "foo.exe\0.png". This file name might pass security checks (i.e. + * checks for the extension ".png"), while, depending on the underlying + * C library, it might create a file named "foo.exe", as the NUL + * character is the string terminator in C. + */ +public class InvalidFileNameException extends RuntimeException { + private static final long serialVersionUID = 7922042602454350470L; + private final String name; + + /** + * Creates a new instance. + * @param pName The file name causing the exception. + * @param pMessage A human readable error message. + */ + public InvalidFileNameException(String pName, String pMessage) { + super(pMessage); + name = pName; + } + + /** + * Returns the invalid file name. + */ + public String getName() { + return name; + } +} diff --git a/source/my/frame/src/frame/upload/MultipartStream.java b/source/my/frame/src/frame/upload/MultipartStream.java new file mode 100644 index 0000000..b364ed1 --- /dev/null +++ b/source/my/frame/src/frame/upload/MultipartStream.java @@ -0,0 +1,1010 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import frame.upload.FileItemStream; +import frame.upload.MultipartStream; +import frame.upload.ProgressListener; + +import frame.upload.util.Closeable; +import frame.upload.util.Streams; + +/** + * <p> Low level API for processing file uploads. + * + * <p> This class can be used to process data streams conforming to MIME + * 'multipart' format as defined in + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Arbitrarily + * large amounts of data in the stream can be processed under constant + * memory usage. + * + * <p> The format of the stream is defined in the following way:<br> + * + * <code> + * multipart-body := preamble 1*encapsulation close-delimiter epilogue<br> + * encapsulation := delimiter body CRLF<br> + * delimiter := "--" boundary CRLF<br> + * close-delimiter := "--" boudary "--"<br> + * preamble := <ignore><br> + * epilogue := <ignore><br> + * body := header-part CRLF body-part<br> + * header-part := 1*header CRLF<br> + * header := header-name ":" header-value<br> + * header-name := <printable ascii characters except ":"><br> + * header-value := <any ascii characters except CR & LF><br> + * body-data := <arbitrary data><br> + * </code> + * + * <p>Note that body-data can contain another mulipart entity. There + * is limited support for single pass processing of such nested + * streams. The nested stream is <strong>required</strong> to have a + * boundary token of the same length as the parent stream (see {@link + * #setBoundary(byte[])}). + * + * <p>Here is an example of usage of this class.<br> + * + * <pre> + * try { + * MultipartStream multipartStream = new MultipartStream(input, boundary); + * boolean nextPart = multipartStream.skipPreamble(); + * OutputStream output; + * while(nextPart) { + * String header = multipartStream.readHeaders(); + * // process headers + * // create some output stream + * multipartStream.readBodyData(output); + * nextPart = multipartStream.readBoundary(); + * } + * } catch(MultipartStream.MalformedStreamException e) { + * // the stream failed to follow required syntax + * } catch(IOException e) { + * // a read or write error occurred + * } + * </pre> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @version $Id: MultipartStream.java 735374 2009-01-18 02:18:45Z jochen $ + */ +public class MultipartStream { + /** + * Internal class, which is used to invoke the + * {@link ProgressListener}. + */ + public static class ProgressNotifier { + /** The listener to invoke. + */ + private final ProgressListener listener; + /** Number of expected bytes, if known, or -1. + */ + private final long contentLength; + /** Number of bytes, which have been read so far. + */ + private long bytesRead; + /** Number of items, which have been read so far. + */ + private int items; + /** Creates a new instance with the given listener + * and content length. + * @param pListener The listener to invoke. + * @param pContentLength The expected content length. + */ + ProgressNotifier(ProgressListener pListener, long pContentLength) { + listener = pListener; + contentLength = pContentLength; + } + /** Called to indicate that bytes have been read. + * @param pBytes Number of bytes, which have been read. + */ + void noteBytesRead(int pBytes) { + /* Indicates, that the given number of bytes have been read from + * the input stream. + */ + bytesRead += pBytes; + notifyListener(); + } + /** Called to indicate, that a new file item has been detected. + */ + void noteItem() { + ++items; + notifyListener(); + } + /** Called for notifying the listener. + */ + private void notifyListener() { + if (listener != null) { + listener.update(bytesRead, contentLength, items); + } + } + } + + // ----------------------------------------------------- Manifest constants + + + /** + * The Carriage Return ASCII character value. + */ + public static final byte CR = 0x0D; + + + /** + * The Line Feed ASCII character value. + */ + public static final byte LF = 0x0A; + + + /** + * The dash (-) ASCII character value. + */ + public static final byte DASH = 0x2D; + + + /** + * The maximum length of <code>header-part</code> that will be + * processed (10 kilobytes = 10240 bytes.). + */ + public static final int HEADER_PART_SIZE_MAX = 10240; + + + /** + * The default length of the buffer used for processing a request. + */ + protected static final int DEFAULT_BUFSIZE = 4096; + + + /** + * A byte sequence that marks the end of <code>header-part</code> + * (<code>CRLFCRLF</code>). + */ + protected static final byte[] HEADER_SEPARATOR = { + CR, LF, CR, LF }; + + + /** + * A byte sequence that that follows a delimiter that will be + * followed by an encapsulation (<code>CRLF</code>). + */ + protected static final byte[] FIELD_SEPARATOR = { + CR, LF}; + + + /** + * A byte sequence that that follows a delimiter of the last + * encapsulation in the stream (<code>--</code>). + */ + protected static final byte[] STREAM_TERMINATOR = { + DASH, DASH}; + + + /** + * A byte sequence that precedes a boundary (<code>CRLF--</code>). + */ + protected static final byte[] BOUNDARY_PREFIX = { + CR, LF, DASH, DASH}; + + + // ----------------------------------------------------------- Data members + + + /** + * The input stream from which data is read. + */ + private final InputStream input; + + + /** + * The length of the boundary token plus the leading <code>CRLF--</code>. + */ + private int boundaryLength; + + + /** + * The amount of data, in bytes, that must be kept in the buffer in order + * to detect delimiters reliably. + */ + private int keepRegion; + + + /** + * The byte sequence that partitions the stream. + */ + private byte[] boundary; + + + /** + * The length of the buffer used for processing the request. + */ + private final int bufSize; + + + /** + * The buffer used for processing the request. + */ + private final byte[] buffer; + + + /** + * The index of first valid character in the buffer. + * <br> + * 0 <= head < bufSize + */ + private int head; + + + /** + * The index of last valid characer in the buffer + 1. + * <br> + * 0 <= tail <= bufSize + */ + private int tail; + + + /** + * The content encoding to use when reading headers. + */ + private String headerEncoding; + + + /** + * The progress notifier, if any, or null. + */ + private final ProgressNotifier notifier; + + // ----------------------------------------------------------- Constructors + + /** + * Creates a new instance. + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * frame.upload.MultipartStream.ProgressNotifier)}, + * or {@link #MultipartStream(InputStream, byte[], int, + * frame.upload.MultipartStream.ProgressNotifier)} + */ + public MultipartStream() { + this(null, null, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer + * and no progress notifier. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + * @deprecated Use {@link #MultipartStream(InputStream, byte[], int, + * frame.upload.MultipartStream.ProgressNotifier)}. + */ + public MultipartStream(InputStream input, byte[] boundary, int bufSize) { + this(input, boundary, bufSize, null); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a custom size buffer. + * + * <p> Note that the buffer must be at least big enough to contain the + * boundary string, plus 4 characters for CR/LF and double dash, plus at + * least one byte of data. Too small a buffer size setting will degrade + * performance. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param bufSize The size of the buffer to be used, in bytes. + * @param pNotifier The notifier, which is used for calling the + * progress listener, if any. + * + * @see #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + int bufSize, + ProgressNotifier pNotifier) { + this.input = input; + this.bufSize = bufSize; + this.buffer = new byte[bufSize]; + this.notifier = pNotifier; + + // We prepend CR/LF to the boundary to chop trailng CR/LF from + // body-data tokens. + this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; + this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + this.keepRegion = this.boundary.length; + System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, + BOUNDARY_PREFIX.length); + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + + head = 0; + tail = 0; + } + + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * @param pNotifier An object for calling the progress listener, if any. + * + * + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + MultipartStream(InputStream input, + byte[] boundary, + ProgressNotifier pNotifier) { + this(input, boundary, DEFAULT_BUFSIZE, pNotifier); + } + + /** + * <p> Constructs a <code>MultipartStream</code> with a default size buffer. + * + * @param input The <code>InputStream</code> to serve as a data source. + * @param boundary The token used for dividing the stream into + * <code>encapsulations</code>. + * + * @deprecated Use {@link #MultipartStream(InputStream, byte[], + * MultipartStream.ProgressNotifier)}. + * @see #MultipartStream(InputStream, byte[], int, + * MultipartStream.ProgressNotifier) + */ + public MultipartStream(InputStream input, + byte[] boundary) { + this(input, boundary, DEFAULT_BUFSIZE, null); + } + + // --------------------------------------------------------- Public methods + + + /** + * Retrieves the character encoding used when reading the headers of an + * individual part. When not specified, or <code>null</code>, the platform + * default encoding is used. + + * + * @return The encoding used to read part headers. + */ + public String getHeaderEncoding() { + return headerEncoding; + } + + + /** + * Specifies the character encoding to be used when reading the headers of + * individual parts. When not specified, or <code>null</code>, the platform + * default encoding is used. + * + * @param encoding The encoding used to read part headers. + */ + public void setHeaderEncoding(String encoding) { + headerEncoding = encoding; + } + + + /** + * Reads a byte from the <code>buffer</code>, and refills it as + * necessary. + * + * @return The next byte from the input stream. + * + * @throws IOException if there is no more data available. + */ + public byte readByte() throws IOException { + // Buffer depleted ? + if (head == tail) { + head = 0; + // Refill. + tail = input.read(buffer, head, bufSize); + if (tail == -1) { + // No more data available. + throw new IOException("No more data is available"); + } + if (notifier != null) { + notifier.noteBytesRead(tail); + } + } + return buffer[head++]; + } + + + /** + * Skips a <code>boundary</code> token, and checks whether more + * <code>encapsulations</code> are contained in the stream. + * + * @return <code>true</code> if there are more encapsulations in + * this stream; <code>false</code> otherwise. + * + * @throws MalformedStreamException if the stream ends unexpecetedly or + * fails to follow required syntax. + */ + public boolean readBoundary() + throws MalformedStreamException { + byte[] marker = new byte[2]; + boolean nextChunk = false; + + head += boundaryLength; + try { + marker[0] = readByte(); + if (marker[0] == LF) { + // Work around IE5 Mac bug with input type=image. + // Because the boundary delimiter, not including the trailing + // CRLF, must not appear within any file (RFC 2046, section + // 5.1.1), we know the missing CR is due to a buggy browser + // rather than a file containing something similar to a + // boundary. + return true; + } + + marker[1] = readByte(); + if (arrayequals(marker, STREAM_TERMINATOR, 2)) { + nextChunk = false; + } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) { + nextChunk = true; + } else { + throw new MalformedStreamException( + "Unexpected characters follow a boundary"); + } + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + return nextChunk; + } + + + /** + * <p>Changes the boundary token used for partitioning the stream. + * + * <p>This method allows single pass processing of nested multipart + * streams. + * + * <p>The boundary token of the nested stream is <code>required</code> + * to be of the same length as the boundary token in parent stream. + * + * <p>Restoring the parent stream boundary token after processing of a + * nested stream is left to the application. + * + * @param boundary The boundary to be used for parsing of the nested + * stream. + * + * @throws IllegalBoundaryException if the <code>boundary</code> + * has a different length than the one + * being currently parsed. + */ + public void setBoundary(byte[] boundary) + throws IllegalBoundaryException { + if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) { + throw new IllegalBoundaryException( + "The length of a boundary token can not be changed"); + } + System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length, + boundary.length); + } + + + /** + * <p>Reads the <code>header-part</code> of the current + * <code>encapsulation</code>. + * + * <p>Headers are returned verbatim to the input stream, including the + * trailing <code>CRLF</code> marker. Parsing is left to the + * application. + * + * <p><strong>TODO</strong> allow limiting maximum header size to + * protect against abuse. + * + * @return The <code>header-part</code> of the current encapsulation. + * + * @throws MalformedStreamException if the stream ends unexpecetedly. + */ + public String readHeaders() + throws MalformedStreamException { + int i = 0; + byte b; + // to support multi-byte characters + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int size = 0; + while (i < HEADER_SEPARATOR.length) { + try { + b = readByte(); + } catch (IOException e) { + throw new MalformedStreamException("Stream ended unexpectedly"); + } + if (++size > HEADER_PART_SIZE_MAX) { + throw new MalformedStreamException( + "Header section has more than " + HEADER_PART_SIZE_MAX + + " bytes (maybe it is not properly terminated)"); + } + if (b == HEADER_SEPARATOR[i]) { + i++; + } else { + i = 0; + } + baos.write(b); + } + + String headers = null; + if (headerEncoding != null) { + try { + headers = baos.toString(headerEncoding); + } catch (UnsupportedEncodingException e) { + // Fall back to platform default if specified encoding is not + // supported. + headers = baos.toString(); + } + } else { + headers = baos.toString(); + } + + return headers; + } + + + /** + * <p>Reads <code>body-data</code> from the current + * <code>encapsulation</code> and writes its contents into the + * output <code>Stream</code>. + * + * <p>Arbitrary large amounts of data can be processed by this + * method using a constant size buffer. (see {@link + * #MultipartStream(InputStream,byte[],int, + * MultipartStream.ProgressNotifier) constructor}). + * + * @param output The <code>Stream</code> to write data into. May + * be null, in which case this method is equivalent + * to {@link #discardBodyData()}. + * + * @return the amount of data written. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int readBodyData(OutputStream output) + throws MalformedStreamException, IOException { + final InputStream istream = newInputStream(); + return (int) Streams.copy(istream, output, false); + } + + /** + * Creates a new {@link ItemInputStream}. + * @return A new instance of {@link ItemInputStream}. + */ + ItemInputStream newInputStream() { + return new ItemInputStream(); + } + + /** + * <p> Reads <code>body-data</code> from the current + * <code>encapsulation</code> and discards it. + * + * <p>Use this method to skip encapsulations you don't need or don't + * understand. + * + * @return The amount of data discarded. + * + * @throws MalformedStreamException if the stream ends unexpectedly. + * @throws IOException if an i/o error occurs. + */ + public int discardBodyData() + throws MalformedStreamException, + IOException { + return readBodyData(null); + } + + + /** + * Finds the beginning of the first <code>encapsulation</code>. + * + * @return <code>true</code> if an <code>encapsulation</code> was found in + * the stream. + * + * @throws IOException if an i/o error occurs. + */ + public boolean skipPreamble() + throws IOException { + // First delimiter may be not preceeded with a CRLF. + System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2); + boundaryLength = boundary.length - 2; + try { + // Discard all data up to the delimiter. + discardBodyData(); + + // Read boundary - if succeded, the stream contains an + // encapsulation. + return readBoundary(); + } catch (MalformedStreamException e) { + return false; + } finally { + // Restore delimiter. + System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2); + boundaryLength = boundary.length; + boundary[0] = CR; + boundary[1] = LF; + } + } + + + /** + * Compares <code>count</code> first bytes in the arrays + * <code>a</code> and <code>b</code>. + * + * @param a The first array to compare. + * @param b The second array to compare. + * @param count How many bytes should be compared. + * + * @return <code>true</code> if <code>count</code> first bytes in arrays + * <code>a</code> and <code>b</code> are equal. + */ + public static boolean arrayequals(byte[] a, + byte[] b, + int count) { + for (int i = 0; i < count; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + + /** + * Searches for a byte of specified value in the <code>buffer</code>, + * starting at the specified <code>position</code>. + * + * @param value The value to find. + * @param pos The starting position for searching. + * + * @return The position of byte found, counting from beginning of the + * <code>buffer</code>, or <code>-1</code> if not found. + */ + protected int findByte(byte value, + int pos) { + for (int i = pos; i < tail; i++) { + if (buffer[i] == value) { + return i; + } + } + + return -1; + } + + + /** + * Searches for the <code>boundary</code> in the <code>buffer</code> + * region delimited by <code>head</code> and <code>tail</code>. + * + * @return The position of the boundary found, counting from the + * beginning of the <code>buffer</code>, or <code>-1</code> if + * not found. + */ + protected int findSeparator() { + int first; + int match = 0; + int maxpos = tail - boundaryLength; + for (first = head; + (first <= maxpos) && (match != boundaryLength); + first++) { + first = findByte(boundary[0], first); + if (first == -1 || (first > maxpos)) { + return -1; + } + for (match = 1; match < boundaryLength; match++) { + if (buffer[first + match] != boundary[match]) { + break; + } + } + } + if (match == boundaryLength) { + return first - 1; + } + return -1; + } + + /** + * Thrown to indicate that the input stream fails to follow the + * required syntax. + */ + public static class MalformedStreamException + extends IOException { + /** + * Constructs a <code>MalformedStreamException</code> with no + * detail message. + */ + public MalformedStreamException() { + super(); + } + + /** + * Constructs an <code>MalformedStreamException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public MalformedStreamException(String message) { + super(message); + } + } + + + /** + * Thrown upon attempt of setting an invalid boundary token. + */ + public static class IllegalBoundaryException + extends IOException { + /** + * Constructs an <code>IllegalBoundaryException</code> with no + * detail message. + */ + public IllegalBoundaryException() { + super(); + } + + /** + * Constructs an <code>IllegalBoundaryException</code> with + * the specified detail message. + * + * @param message The detail message. + */ + public IllegalBoundaryException(String message) { + super(message); + } + } + + /** + * An {@link InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream implements Closeable { + /** The number of bytes, which have been read so far. + */ + private long total; + /** The number of bytes, which must be hold, because + * they might be a part of the boundary. + */ + private int pad; + /** The current offset in the buffer. + */ + private int pos; + /** Whether the stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + */ + ItemInputStream() { + findSeparator(); + } + + /** + * Called for finding the separator. + */ + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** + * Returns the number of bytes, which have been read + * by the stream. + * @return Number of bytes, which have been read so far. + */ + public long getBytesRead() { + return total; + } + + /** + * Returns the number of bytes, which are currently + * available, without blocking. + * @throws IOException An I/O error occurs. + * @return Number of bytes in the buffer. + */ + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } + return pos - head; + } + + /** Offset when converting negative bytes to integers. + */ + private static final int BYTE_POSITIVE_OFFSET = 256; + + /** + * Returns the next byte in the stream. + * @return The next byte in the stream, as a non-negative + * integer, or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read() throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + if (b >= 0) { + return b; + } + return b + BYTE_POSITIVE_OFFSET; + } + + /** + * Reads bytes into the given buffer. + * @param b The destination buffer, where to write to. + * @param off Offset of the first byte in the buffer. + * @param len Maximum number of bytes to read. + * @return Number of bytes, which have been actually read, + * or -1 for EOF. + * @throws IOException An I/O error occurred. + */ + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + /** + * Closes the input stream. + * @throws IOException An I/O error occurred. + */ + public void close() throws IOException { + close(false); + } + + /** + * Closes the input stream. + * @param pCloseUnderlying Whether to close the underlying stream + * (hard close) + * @throws IOException An I/O error occurred. + */ + public void close(boolean pCloseUnderlying) throws IOException { + if (closed) { + return; + } + if (pCloseUnderlying) { + closed = true; + input.close(); + } else { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + closed = true; + } + + /** + * Skips the given number of bytes. + * @param bytes Number of bytes to skip. + * @return The number of bytes, which have actually been + * skipped. + * @throws IOException An I/O error occurred. + */ + public long skip(long bytes) throws IOException { + if (closed) { + throw new FileItemStream.ItemSkippedException(); + } + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + /** + * Attempts to read more data. + * @return Number of available bytes + * @throws IOException An I/O error occurred. + */ + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + tail = pad; + + for (;;) { + int bytesRead = input.read(buffer, tail, bufSize - tail); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + final String msg = "Stream ended unexpectedly"; + throw new MalformedStreamException(msg); + } + if (notifier != null) { + notifier.noteBytesRead(bytesRead); + } + tail += bytesRead; + + findSeparator(); + int av = available(); + + if (av > 0 || pos != -1) { + return av; + } + } + } + + /** + * Returns, whether the stream is closed. + * @return True, if the stream is closed, otherwise false. + */ + public boolean isClosed() { + return closed; + } + } +} diff --git a/source/my/frame/src/frame/upload/ParameterParser.java b/source/my/frame/src/frame/upload/ParameterParser.java new file mode 100644 index 0000000..a51e9a3 --- /dev/null +++ b/source/my/frame/src/frame/upload/ParameterParser.java @@ -0,0 +1,329 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.util.HashMap; +import java.util.Map; + +/** + * A simple parser intended to parse sequences of name/value pairs. + * Parameter values are exptected to be enclosed in quotes if they + * contain unsafe characters, such as '=' characters or separators. + * Parameter values are optional and can be omitted. + * + * <p> + * <code>param1 = value; param2 = "anything goes; really"; param3</code> + * </p> + * + * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> + */ + +public class ParameterParser { + /** + * String to be parsed. + */ + private char[] chars = null; + + /** + * Current position in the string. + */ + private int pos = 0; + + /** + * Maximum position in the string. + */ + private int len = 0; + + /** + * Start of a token. + */ + private int i1 = 0; + + /** + * End of a token. + */ + private int i2 = 0; + + /** + * Whether names stored in the map should be converted to lower case. + */ + private boolean lowerCaseNames = false; + + /** + * Default ParameterParser constructor. + */ + public ParameterParser() { + super(); + } + + /** + * Are there any characters left to parse? + * + * @return <tt>true</tt> if there are unparsed characters, + * <tt>false</tt> otherwise. + */ + private boolean hasChar() { + return this.pos < this.len; + } + + /** + * A helper method to process the parsed token. This method removes + * leading and trailing blanks as well as enclosing quotation marks, + * when necessary. + * + * @param quoted <tt>true</tt> if quotation marks are expected, + * <tt>false</tt> otherwise. + * @return the token + */ + private String getToken(boolean quoted) { + // Trim leading white spaces + while ((i1 < i2) && (Character.isWhitespace(chars[i1]))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (Character.isWhitespace(chars[i2 - 1]))) { + i2--; + } + // Strip away quotation marks if necessary + if (quoted) { + if (((i2 - i1) >= 2) + && (chars[i1] == '"') + && (chars[i2 - 1] == '"')) { + i1++; + i2--; + } + } + String result = null; + if (i2 > i1) { + result = new String(chars, i1, i2 - i1); + } + return result; + } + + /** + * Tests if the given character is present in the array of characters. + * + * @param ch the character to test for presense in the array of characters + * @param charray the array of characters to test against + * + * @return <tt>true</tt> if the character is present in the array of + * characters, <tt>false</tt> otherwise. + */ + private boolean isOneOf(char ch, final char[] charray) { + boolean result = false; + for (int i = 0; i < charray.length; i++) { + if (ch == charray[i]) { + result = true; + break; + } + } + return result; + } + + /** + * Parses out a token until any of the given terminators + * is encountered. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered signify the end of the token + * + * @return the token + */ + private String parseToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + while (hasChar()) { + ch = chars[pos]; + if (isOneOf(ch, terminators)) { + break; + } + i2++; + pos++; + } + return getToken(false); + } + + /** + * Parses out a token until any of the given terminators + * is encountered outside the quotation marks. + * + * @param terminators the array of terminating characters. Any of these + * characters when encountered outside the quotation marks signify the end + * of the token + * + * @return the token + */ + private String parseQuotedToken(final char[] terminators) { + char ch; + i1 = pos; + i2 = pos; + boolean quoted = false; + boolean charEscaped = false; + while (hasChar()) { + ch = chars[pos]; + if (!quoted && isOneOf(ch, terminators)) { + break; + } + if (!charEscaped && ch == '"') { + quoted = !quoted; + } + charEscaped = (!charEscaped && ch == '\\'); + i2++; + pos++; + + } + return getToken(true); + } + + /** + * Returns <tt>true</tt> if parameter names are to be converted to lower + * case when name/value pairs are parsed. + * + * @return <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * Otherwise returns <tt>false</tt> + */ + public boolean isLowerCaseNames() { + return this.lowerCaseNames; + } + + /** + * Sets the flag if parameter names are to be converted to lower case when + * name/value pairs are parsed. + * + * @param b <tt>true</tt> if parameter names are to be + * converted to lower case when name/value pairs are parsed. + * <tt>false</tt> otherwise. + */ + public void setLowerCaseNames(boolean b) { + this.lowerCaseNames = b; + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. Multiple separators may be specified and + * the earliest found in the input string is used. + * + * @param str the string that contains a sequence of name/value pairs + * @param separators the name/value pairs separators + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char[] separators) { + if (separators == null || separators.length == 0) { + return new HashMap(); + } + char separator = separators[0]; + if (str != null) { + int idx = str.length(); + for (int i = 0; i < separators.length; i++) { + int tmp = str.indexOf(separators[i]); + if (tmp != -1) { + if (tmp < idx) { + idx = tmp; + separator = separators[i]; + } + } + } + } + return parse(str, separator); + } + + /** + * Extracts a map of name/value pairs from the given string. Names are + * expected to be unique. + * + * @param str the string that contains a sequence of name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final String str, char separator) { + if (str == null) { + return new HashMap(); + } + return parse(str.toCharArray(), separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse(final char[] chars, char separator) { + if (chars == null) { + return new HashMap(); + } + return parse(chars, 0, chars.length, separator); + } + + /** + * Extracts a map of name/value pairs from the given array of + * characters. Names are expected to be unique. + * + * @param chars the array of characters that contains a sequence of + * name/value pairs + * @param offset - the initial offset. + * @param length - the length. + * @param separator the name/value pairs separator + * + * @return a map of name/value pairs + */ + public Map parse( + final char[] chars, + int offset, + int length, + char separator) { + + if (chars == null) { + return new HashMap(); + } + HashMap params = new HashMap(); + this.chars = chars; + this.pos = offset; + this.len = length; + + String paramName = null; + String paramValue = null; + while (hasChar()) { + paramName = parseToken(new char[] { + '=', separator }); + paramValue = null; + if (hasChar() && (chars[pos] == '=')) { + pos++; // skip '=' + paramValue = parseQuotedToken(new char[] { + separator }); + } + if (hasChar() && (chars[pos] == separator)) { + pos++; // skip separator + } + if ((paramName != null) && (paramName.length() > 0)) { + if (this.lowerCaseNames) { + paramName = paramName.toLowerCase(); + } + params.put(paramName, paramValue); + } + } + return params; + } +} diff --git a/source/my/frame/src/frame/upload/ProgressListener.java b/source/my/frame/src/frame/upload/ProgressListener.java new file mode 100644 index 0000000..835c2fa --- /dev/null +++ b/source/my/frame/src/frame/upload/ProgressListener.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import frame.upload.ProgressListener; + + +/** + * The {@link ProgressListener} may be used to display a progress bar + * or do stuff like that. + */ +public interface ProgressListener { + /** Updates the listeners status information. + * @param pBytesRead The total number of bytes, which have been read + * so far. + * @param pContentLength The total number of bytes, which are being + * read. May be -1, if this number is unknown. + * @param pItems The number of the field, which is currently being + * read. (0 = no item so far, 1 = first item is being read, ...) + */ + void update(long pBytesRead, long pContentLength, int pItems); +} diff --git a/source/my/frame/src/frame/upload/RequestContext.java b/source/my/frame/src/frame/upload/RequestContext.java new file mode 100644 index 0000000..1a0fe64 --- /dev/null +++ b/source/my/frame/src/frame/upload/RequestContext.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload; + +import java.io.InputStream; +import java.io.IOException; + +/** + * <p>Abstracts access to the request information needed for file uploads. This + * interfsace should be implemented for each type of request that may be + * handled by FileUpload, such as servlets and portlets.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: RequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public interface RequestContext { + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + String getCharacterEncoding(); + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + String getContentType(); + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + int getContentLength(); + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + InputStream getInputStream() throws IOException; +} diff --git a/source/my/frame/src/frame/upload/disk/DiskFileItem.java b/source/my/frame/src/frame/upload/disk/DiskFileItem.java new file mode 100644 index 0000000..692c681 --- /dev/null +++ b/source/my/frame/src/frame/upload/disk/DiskFileItem.java @@ -0,0 +1,336 @@ +package frame.upload.disk; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import frame.upload.disk.DiskFileItem; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.DeferredFileOutputStream; + +import frame.upload.FileItem; +import frame.upload.FileItemHeaders; +import frame.upload.FileItemHeadersSupport; +import frame.upload.FileUploadException; +import frame.upload.ParameterParser; +import frame.upload.util.Streams; + + +public class DiskFileItem + implements FileItem, FileItemHeadersSupport { + + private static final long serialVersionUID = 2237570099615271025L; + public static final String DEFAULT_CHARSET = "ISO-8859-1"; + private static final String UID = new java.rmi.server.UID().toString().replace(':', '_').replace('-', '_'); + private static int counter = 0; + private String fieldName; + private String contentType; + private boolean isFormField; + private String fileName; + private long size = -1; + private int sizeThreshold; + private File repository; + private byte[] cachedContent; + private transient DeferredFileOutputStream dfos; + private transient File tempFile; + private File dfosFile; + private FileItemHeaders headers; + + public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) { + this.fieldName = fieldName; + this.contentType = contentType; + this.isFormField = isFormField; + this.fileName = fileName; + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public InputStream getInputStream() throws IOException { + if (!isInMemory()) { + return new FileInputStream(dfos.getFile()); + } + + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return new ByteArrayInputStream(cachedContent); + } + + public String getContentType() { + return contentType; + } + public String getCharSet() { + ParameterParser parser = new ParameterParser(); + parser.setLowerCaseNames(true); + Map params = parser.parse(getContentType(), ';'); + return (String) params.get("charset"); + } + + public String getName() { + return Streams.checkFileName(fileName); + } + + public boolean isInMemory() { + if (cachedContent != null) { + return true; + } + return dfos.isInMemory(); + } + + public long getSize() { + if (size >= 0) { + return size; + } + else if (cachedContent != null) { + return cachedContent.length; + } + else if (dfos.isInMemory()) { + return dfos.getData().length; + } + else { + return dfos.getFile().length(); + } + } + + public byte[] get() { + if (isInMemory()) { + if (cachedContent == null) { + cachedContent = dfos.getData(); + } + return cachedContent; + } + + byte[] fileData = new byte[(int) getSize()]; + FileInputStream fis = null; + + try { + fis = new FileInputStream(dfos.getFile()); + fis.read(fileData); + } catch (IOException e) { + fileData = null; + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + // ignore + } + } + } + + return fileData; + } + + public String getString(final String charset) + throws UnsupportedEncodingException { + return new String(get(), charset); + } + + public String getString() { + byte[] rawdata = get(); + String charset = getCharSet(); + if (charset == null) { + charset = DEFAULT_CHARSET; + } + try { + return new String(rawdata, charset); + } catch (UnsupportedEncodingException e) { + return new String(rawdata); + } + } + + public void write(File file) throws Exception { + if (isInMemory()) { + FileOutputStream fout = null; + try { + fout = new FileOutputStream(file); + fout.write(get()); + } finally { + if (fout != null) { + fout.close(); + } + } + } else { + File outputFile = getStoreLocation(); + if (outputFile != null) { + // Save the length of the file + size = outputFile.length(); + /* + * The uploaded file is being stored on disk + * in a temporary location so move it to the + * desired file. + */ + if (!outputFile.renameTo(file)) { + BufferedInputStream in = null; + BufferedOutputStream out = null; + try { + in = new BufferedInputStream( + new FileInputStream(outputFile)); + out = new BufferedOutputStream( + new FileOutputStream(file)); + IOUtils.copy(in, out); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + } + } + } else { + /* + * For whatever reason we cannot write the + * file to disk. + */ + throw new FileUploadException( + "Cannot write uploaded file to disk!"); + } + } + } + + + public void delete() { + cachedContent = null; + File outputFile = getStoreLocation(); + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public boolean isFormField() { + return isFormField; + } + + public void setFormField(boolean state) { + isFormField = state; + } + + public OutputStream getOutputStream() + throws IOException { + if (dfos == null) { + File outputFile = getTempFile(); + dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); + } + return dfos; + } + + public File getStoreLocation() { + return dfos == null ? null : dfos.getFile(); + } + + protected void finalize() { + File outputFile = dfos.getFile(); + + if (outputFile != null && outputFile.exists()) { + outputFile.delete(); + } + } + + protected File getTempFile() { + if (tempFile == null) { + File tempDir = repository; + if (tempDir == null) { + tempDir = new File(System.getProperty("java.io.tmpdir")); + } + + String tempFileName = + "upload_" + UID + "_" + getUniqueId() + ".tmp"; + + tempFile = new File(tempDir, tempFileName); + } + return tempFile; + } + + private static String getUniqueId() { + final int limit = 100000000; + int current; + synchronized (DiskFileItem.class) { + current = counter++; + } + String id = Integer.toString(current); + + // If you manage to get more than 100 million of ids, you'll + // start getting ids longer than 8 characters. + if (current < limit) { + id = ("00000000" + id).substring(id.length()); + } + return id; + } + + public String toString() { + return "name=" + this.getName() + + ", StoreLocation=" + + String.valueOf(this.getStoreLocation()) + + ", size=" + + this.getSize() + + "bytes, " + + "isFormField=" + isFormField() + + ", FieldName=" + + this.getFieldName(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + // Read the data + if (dfos.isInMemory()) { + cachedContent = get(); + } else { + cachedContent = null; + dfosFile = dfos.getFile(); + } + + // write out values + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + // read values + in.defaultReadObject(); + + OutputStream output = getOutputStream(); + if (cachedContent != null) { + output.write(cachedContent); + } else { + FileInputStream input = new FileInputStream(dfosFile); + IOUtils.copy(input, output); + dfosFile.delete(); + dfosFile = null; + } + output.close(); + + cachedContent = null; + } + + public FileItemHeaders getHeaders() { + return headers; + } + + public void setHeaders(FileItemHeaders pHeaders) { + headers = pHeaders; + } +} diff --git a/source/my/frame/src/frame/upload/disk/DiskFileItemFactory.java b/source/my/frame/src/frame/upload/disk/DiskFileItemFactory.java new file mode 100644 index 0000000..024a0bf --- /dev/null +++ b/source/my/frame/src/frame/upload/disk/DiskFileItemFactory.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.disk; + +import java.io.File; + +import frame.upload.disk.DiskFileItem; +import org.apache.commons.io.FileCleaningTracker; + +import frame.upload.FileItem; +import frame.upload.FileItemFactory; + + +public class DiskFileItemFactory implements FileItemFactory { + + public static final int DEFAULT_SIZE_THRESHOLD = 10240; + private File repository; + private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + private FileCleaningTracker fileCleaningTracker; + + public DiskFileItemFactory() { + this(DEFAULT_SIZE_THRESHOLD, null); + } + + public DiskFileItemFactory(int sizeThreshold, File repository) { + this.sizeThreshold = sizeThreshold; + this.repository = repository; + } + + public File getRepository() { + return repository; + } + + + public void setRepository(File repository) { + this.repository = repository; + } + + public int getSizeThreshold() { + return sizeThreshold; + } + + public void setSizeThreshold(int sizeThreshold) { + this.sizeThreshold = sizeThreshold; + } + + + public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + FileCleaningTracker tracker = getFileCleaningTracker(); + if (tracker != null) { + tracker.track(result.getTempFile(), this); + } + return result; + } + + public FileCleaningTracker getFileCleaningTracker() { + return fileCleaningTracker; + } + + public void setFileCleaningTracker(FileCleaningTracker pTracker) { + fileCleaningTracker = pTracker; + } +} diff --git a/source/my/frame/src/frame/upload/portlet/PortletFileUpload.java b/source/my/frame/src/frame/upload/portlet/PortletFileUpload.java new file mode 100644 index 0000000..9f9b8a0 --- /dev/null +++ b/source/my/frame/src/frame/upload/portlet/PortletFileUpload.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.portlet; + +import java.io.IOException; +import java.util.List; + +import javax.portlet.ActionRequest; + +import frame.upload.portlet.PortletRequestContext; + +import frame.upload.FileItemFactory; +import frame.upload.FileItemIterator; +import frame.upload.FileUpload; +import frame.upload.FileUploadBase; +import frame.upload.FileUploadException; + +/** + * <p>High level API for processing file uploads.</p> + * + * <p>This class handles multiple files per single HTML widget, sent using + * <code>multipart/mixed</code> encoding type, as specified by + * <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. Use {@link + * #parseRequest(javax.servlet.http.HttpServletRequest)} to acquire a list + * of {@link frame.upload.FileItem FileItems} associated + * with a given HTML widget.</p> + * + * <p>How the data for individual parts is stored is determined by the factory + * used to create them; a given part may be in memory, on disk, or somewhere + * else.</p> + * + * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> + * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> + * @author <a href="mailto:jmcnally@collab.net">John McNally</a> + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * @author Sean C. Sullivan + * + * @since FileUpload 1.1 + * + * @version $Id: PortletFileUpload.java 479484 2006-11-27 01:06:53Z jochen $ + */ +public class PortletFileUpload extends FileUpload { + + // ---------------------------------------------------------- Class methods + + + /** + * Utility method that determines whether the request contains multipart + * content. + * + * @param request The portlet request to be evaluated. Must be non-null. + * + * @return <code>true</code> if the request is multipart; + * <code>false</code> otherwise. + */ + public static final boolean isMultipartContent(ActionRequest request) { + return FileUploadBase.isMultipartContent( + new PortletRequestContext(request)); + } + + + // ----------------------------------------------------------- Constructors + + + /** + * Constructs an uninitialised instance of this class. A factory must be + * configured, using <code>setFileItemFactory()</code>, before attempting + * to parse requests. + * + * @see FileUpload#FileUpload(FileItemFactory) + */ + public PortletFileUpload() { + super(); + } + + + /** + * Constructs an instance of this class which uses the supplied factory to + * create <code>FileItem</code> instances. + * + * @see FileUpload#FileUpload() + * @param fileItemFactory The factory to use for creating file items. + */ + public PortletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + + // --------------------------------------------------------- Public methods + + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return A list of <code>FileItem</code> instances parsed from the + * request, in the order that they were transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + */ + public List /* FileItem */ parseRequest(ActionRequest request) + throws FileUploadException { + return parseRequest(new PortletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The portlet request to be parsed. + * + * @return An iterator to instances of <code>FileItemStream</code> + * parsed from the request, in the order that they were + * transmitted. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * @throws IOException An I/O error occurred. This may be a network + * error while communicating with the client or a problem while + * storing the uploaded content. + */ + public FileItemIterator getItemIterator(ActionRequest request) + throws FileUploadException, IOException { + return super.getItemIterator(new PortletRequestContext(request)); + } +} diff --git a/source/my/frame/src/frame/upload/portlet/PortletRequestContext.java b/source/my/frame/src/frame/upload/portlet/PortletRequestContext.java new file mode 100644 index 0000000..a012608 --- /dev/null +++ b/source/my/frame/src/frame/upload/portlet/PortletRequestContext.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.portlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.portlet.ActionRequest; + +import frame.upload.RequestContext; + +/** + * <p>Provides access to the request information needed for a request made to + * a portlet.</p> + * + * @author <a href="mailto:martinc@apache.org">Martin Cooper</a> + * + * @since FileUpload 1.1 + * + * @version $Id: PortletRequestContext.java 479262 2006-11-26 03:09:24Z niallp $ + */ +public class PortletRequestContext implements RequestContext { + + // ----------------------------------------------------- Instance Variables + + /** + * The request for which the context is being provided. + */ + private ActionRequest request; + + + // ----------------------------------------------------------- Constructors + + /** + * Construct a context for this request. + * + * @param request The request to which this context applies. + */ + public PortletRequestContext(ActionRequest request) { + this.request = request; + } + + + // --------------------------------------------------------- Public Methods + + /** + * Retrieve the character encoding for the request. + * + * @return The character encoding for the request. + */ + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + /** + * Retrieve the content type of the request. + * + * @return The content type of the request. + */ + public String getContentType() { + return request.getContentType(); + } + + /** + * Retrieve the content length of the request. + * + * @return The content length of the request. + */ + public int getContentLength() { + return request.getContentLength(); + } + + /** + * Retrieve the input stream for the request. + * + * @return The input stream for the request. + * + * @throws IOException if a problem occurs. + */ + public InputStream getInputStream() throws IOException { + return request.getPortletInputStream(); + } + + /** + * Returns a string representation of this object. + * + * @return a string representation of this object. + */ + public String toString() { + return "ContentLength=" + + this.getContentLength() + + ", ContentType=" + + this.getContentType(); + } + +} diff --git a/source/my/frame/src/frame/upload/servlet/FileCleanerCleanup.java b/source/my/frame/src/frame/upload/servlet/FileCleanerCleanup.java new file mode 100644 index 0000000..7b2915b --- /dev/null +++ b/source/my/frame/src/frame/upload/servlet/FileCleanerCleanup.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextListener; +import javax.servlet.ServletContextEvent; + +import frame.upload.servlet.FileCleanerCleanup; +import org.apache.commons.io.FileCleaningTracker; + + +/** + * A servlet context listener, which ensures that the + * {@link org.apache.commons.io.FileCleaner FileCleaner's} + * reaper thread is terminated, + * when the web application is destroyed. + */ +public class FileCleanerCleanup implements ServletContextListener { + /** + * Attribute name, which is used for storing an instance of + * {@link FileCleaningTracker} in the web application. + */ + public static final String FILE_CLEANING_TRACKER_ATTRIBUTE + = FileCleanerCleanup.class.getName() + ".FileCleaningTracker"; + + /** + * Returns the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to query + * @return The contexts tracker + */ + public static FileCleaningTracker + getFileCleaningTracker(ServletContext pServletContext) { + return (FileCleaningTracker) + pServletContext.getAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE); + } + + /** + * Sets the instance of {@link FileCleaningTracker}, which is + * associated with the given {@link ServletContext}. + * @param pServletContext The servlet context to modify + * @param pTracker The tracker to set + */ + public static void setFileCleaningTracker(ServletContext pServletContext, + FileCleaningTracker pTracker) { + pServletContext.setAttribute(FILE_CLEANING_TRACKER_ATTRIBUTE, pTracker); + } + + /** + * Called when the web application is initialized. Does + * nothing. + * @param sce The servlet context, used for calling + * {@link #setFileCleaningTracker(ServletContext, FileCleaningTracker)}. + */ + public void contextInitialized(ServletContextEvent sce) { + setFileCleaningTracker(sce.getServletContext(), + new FileCleaningTracker()); + } + + /** + * Called when the web application is being destroyed. + * Calls {@link FileCleaningTracker#exitWhenFinished()}. + * @param sce The servlet context, used for calling + * {@link #getFileCleaningTracker(ServletContext)}. + */ + public void contextDestroyed(ServletContextEvent sce) { + getFileCleaningTracker(sce.getServletContext()).exitWhenFinished(); + } +} diff --git a/source/my/frame/src/frame/upload/servlet/ServletFileUpload.java b/source/my/frame/src/frame/upload/servlet/ServletFileUpload.java new file mode 100644 index 0000000..b49d687 --- /dev/null +++ b/source/my/frame/src/frame/upload/servlet/ServletFileUpload.java @@ -0,0 +1,46 @@ +package frame.upload.servlet; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import frame.upload.servlet.ServletRequestContext; + +import frame.upload.FileItemFactory; +import frame.upload.FileItemIterator; +import frame.upload.FileUpload; +import frame.upload.FileUploadException; + + +public class ServletFileUpload extends FileUpload { + + public static final boolean isMultipartContent(HttpServletRequest request) { + String contentType = request.getContentType(); + + if (contentType == null) { + return false; + } + else if (contentType.toLowerCase().startsWith("multipart/")) { + return true; + } + + return false; + } + + public ServletFileUpload() { + super(); + } + + public ServletFileUpload(FileItemFactory fileItemFactory) { + super(fileItemFactory); + } + + public List parseRequest(HttpServletRequest request) throws FileUploadException { + return parseRequest(new ServletRequestContext(request)); + } + + public FileItemIterator getItemIterator(HttpServletRequest request) throws FileUploadException, IOException { + return super.getItemIterator(new ServletRequestContext(request)); + } +} diff --git a/source/my/frame/src/frame/upload/servlet/ServletRequestContext.java b/source/my/frame/src/frame/upload/servlet/ServletRequestContext.java new file mode 100644 index 0000000..c7f9f59 --- /dev/null +++ b/source/my/frame/src/frame/upload/servlet/ServletRequestContext.java @@ -0,0 +1,36 @@ +package frame.upload.servlet; + +import java.io.InputStream; +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import frame.upload.RequestContext; + +public class ServletRequestContext implements RequestContext { + + private HttpServletRequest request; + + public ServletRequestContext(HttpServletRequest request) { + this.request = request; + } + + public String getCharacterEncoding() { + return request.getCharacterEncoding(); + } + + public String getContentType() { + return request.getContentType(); + } + + public int getContentLength() { + return request.getContentLength(); + } + + public InputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + public String toString() { + return "ContentLength=" + this.getContentLength() + ", ContentType=" + this.getContentType(); + } +} diff --git a/source/my/frame/src/frame/upload/util/Closeable.java b/source/my/frame/src/frame/upload/util/Closeable.java new file mode 100644 index 0000000..07d3a23 --- /dev/null +++ b/source/my/frame/src/frame/upload/util/Closeable.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.IOException; + + +/** + * Interface of an object, which may be closed. + */ +public interface Closeable { + /** + * Closes the object. + * @throws IOException An I/O error occurred. + */ + void close() throws IOException; + + /** + * Returns, whether the object is already closed. + * @return True, if the object is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + boolean isClosed() throws IOException; +} diff --git a/source/my/frame/src/frame/upload/util/FileItemHeadersImpl.java b/source/my/frame/src/frame/upload/util/FileItemHeadersImpl.java new file mode 100644 index 0000000..5814db8 --- /dev/null +++ b/source/my/frame/src/frame/upload/util/FileItemHeadersImpl.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import frame.upload.FileItemHeaders; + + +/** + * Default implementation of the {@link FileItemHeaders} interface. + * + * @author Michael C. Macaluso + * @since 1.3 + */ +public class FileItemHeadersImpl implements FileItemHeaders, Serializable { + private static final long serialVersionUID = -4455695752627032559L; + + /** + * Map of <code>String</code> keys to a <code>List</code> of + * <code>String</code> instances. + */ + private final Map headerNameToValueListMap = new HashMap(); + + /** + * List to preserve order of headers as added. This would not be + * needed if a <code>LinkedHashMap</code> could be used, but don't + * want to depend on 1.4. + */ + private final List headerNameList = new ArrayList(); + + public String getHeader(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return null; + } + return (String) headerValueList.get(0); + } + + public Iterator getHeaderNames() { + return headerNameList.iterator(); + } + + public Iterator getHeaders(String name) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + return Collections.EMPTY_LIST.iterator(); + } + return headerValueList.iterator(); + } + + /** + * Method to add header values to this instance. + * + * @param name name of this header + * @param value value of this header + */ + public synchronized void addHeader(String name, String value) { + String nameLower = name.toLowerCase(); + List headerValueList = (List) headerNameToValueListMap.get(nameLower); + if (null == headerValueList) { + headerValueList = new ArrayList(); + headerNameToValueListMap.put(nameLower, headerValueList); + headerNameList.add(nameLower); + } + headerValueList.add(value); + } +} diff --git a/source/my/frame/src/frame/upload/util/LimitedInputStream.java b/source/my/frame/src/frame/upload/util/LimitedInputStream.java new file mode 100644 index 0000000..5936f39 --- /dev/null +++ b/source/my/frame/src/frame/upload/util/LimitedInputStream.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +import frame.upload.util.Closeable; + + +/** + * An input stream, which limits its data size. This stream is + * used, if the content length is unknown. + */ +public abstract class LimitedInputStream + extends FilterInputStream implements Closeable { + /** + * The maximum size of an item, in bytes. + */ + private long sizeMax; + /** + * The current number of bytes. + */ + private long count; + /** + * Whether this stream is already closed. + */ + private boolean closed; + + /** + * Creates a new instance. + * @param pIn The input stream, which shall be limited. + * @param pSizeMax The limit; no more than this number of bytes + * shall be returned by the source stream. + */ + public LimitedInputStream(InputStream pIn, long pSizeMax) { + super(pIn); + sizeMax = pSizeMax; + } + + /** + * Called to indicate, that the input streams limit has + * been exceeded. + * @param pSizeMax The input streams limit, in bytes. + * @param pCount The actual number of bytes. + * @throws IOException The called method is expected + * to raise an IOException. + */ + protected abstract void raiseError(long pSizeMax, long pCount) + throws IOException; + + /** Called to check, whether the input streams + * limit is reached. + * @throws IOException The given limit is exceeded. + */ + private void checkLimit() throws IOException { + if (count > sizeMax) { + raiseError(sizeMax, count); + } + } + + /** + * Reads the next byte of data from this input stream. The value + * byte is returned as an <code>int</code> in the range + * <code>0</code> to <code>255</code>. If no byte is available + * because the end of the stream has been reached, the value + * <code>-1</code> is returned. This method blocks until input data + * is available, the end of the stream is detected, or an exception + * is thrown. + * <p> + * This method + * simply performs <code>in.read()</code> and returns the result. + * + * @return the next byte of data, or <code>-1</code> if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read() throws IOException { + int res = super.read(); + if (res != -1) { + count++; + checkLimit(); + } + return res; + } + + /** + * Reads up to <code>len</code> bytes of data from this input stream + * into an array of bytes. If <code>len</code> is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and <code>0</code> is returned. + * <p> + * This method simply performs <code>in.read(b, off, len)</code> + * and returns the result. + * + * @param b the buffer into which the data is read. + * @param off The start offset in the destination array + * <code>b</code>. + * @param len the maximum number of bytes read. + * @return the total number of bytes read into the buffer, or + * <code>-1</code> if there is no more data because the end of + * the stream has been reached. + * @exception NullPointerException If <code>b</code> is <code>null</code>. + * @exception IndexOutOfBoundsException If <code>off</code> is negative, + * <code>len</code> is negative, or <code>len</code> is greater than + * <code>b.length - off</code> + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public int read(byte[] b, int off, int len) throws IOException { + int res = super.read(b, off, len); + if (res > 0) { + count += res; + checkLimit(); + } + return res; + } + + /** + * Returns, whether this stream is already closed. + * @return True, if the stream is closed, otherwise false. + * @throws IOException An I/O error occurred. + */ + public boolean isClosed() throws IOException { + return closed; + } + + /** + * Closes this input stream and releases any system resources + * associated with the stream. + * This + * method simply performs <code>in.close()</code>. + * + * @exception IOException if an I/O error occurs. + * @see java.io.FilterInputStream#in + */ + public void close() throws IOException { + closed = true; + super.close(); + } +} diff --git a/source/my/frame/src/frame/upload/util/Streams.java b/source/my/frame/src/frame/upload/util/Streams.java new file mode 100644 index 0000000..57c00be --- /dev/null +++ b/source/my/frame/src/frame/upload/util/Streams.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 frame.upload.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import frame.upload.InvalidFileNameException; + + +/** Utility class for working with streams. + */ +public final class Streams { + /** + * Private constructor, to prevent instantiation. + * This class has only static methods. + */ + private Streams() { + // Does nothing + } + + /** + * Default buffer size for use in + * {@link #copy(InputStream, OutputStream, boolean)}. + */ + private static final int DEFAULT_BUFFER_SIZE = 8192; + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. Shortcut for + * <pre> + * copy(pInputStream, pOutputStream, new byte[8192]); + * </pre> + * @param pInputStream The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOutputStream The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pInputStream, + OutputStream pOutputStream, boolean pClose) + throws IOException { + return copy(pInputStream, pOutputStream, pClose, + new byte[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies the contents of the given {@link InputStream} + * to the given {@link OutputStream}. + * @param pIn The input stream, which is being read. + * It is guaranteed, that {@link InputStream#close()} is called + * on the stream. + * @param pOut The output stream, to which data should + * be written. May be null, in which case the input streams + * contents are simply discarded. + * @param pClose True guarantees, that {@link OutputStream#close()} + * is called on the stream. False indicates, that only + * {@link OutputStream#flush()} should be called finally. + * @param pBuffer Temporary buffer, which is to be used for + * copying data. + * @return Number of bytes, which have been copied. + * @throws IOException An I/O error occurred. + */ + public static long copy(InputStream pIn, + OutputStream pOut, boolean pClose, + byte[] pBuffer) + throws IOException { + OutputStream out = pOut; + InputStream in = pIn; + try { + long total = 0; + for (;;) { + int res = in.read(pBuffer); + if (res == -1) { + break; + } + if (res > 0) { + total += res; + if (out != null) { + out.write(pBuffer, 0, res); + } + } + } + if (out != null) { + if (pClose) { + out.close(); + } else { + out.flush(); + } + out = null; + } + in.close(); + in = null; + return total; + } finally { + if (in != null) { + try { + in.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + if (pClose && out != null) { + try { + out.close(); + } catch (Throwable t) { + /* Ignore me */ + } + } + } + } + + /** + * This convenience method allows to read a + * {@link frame.upload.FileItemStream}'s + * content into a string. The platform's default character encoding + * is used for converting bytes into characters. + * @param pStream The input stream to read. + * @see #asString(InputStream, String) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(); + } + + /** + * This convenience method allows to read a + * {@link frame.upload.FileItemStream}'s + * content into a string, using the given character encoding. + * @param pStream The input stream to read. + * @param pEncoding The character encoding, typically "UTF-8". + * @see #asString(InputStream) + * @return The streams contents, as a string. + * @throws IOException An I/O error occurred. + */ + public static String asString(InputStream pStream, String pEncoding) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy(pStream, baos, true); + return baos.toString(pEncoding); + } + + /** + * Checks, whether the given file name is valid in the sense, + * that it doesn't contain any NUL characters. If the file name + * is valid, it will be returned without any modifications. Otherwise, + * an {@link InvalidFileNameException} is raised. + * @param pFileName The file name to check + * @return Unmodified file name, if valid. + * @throws InvalidFileNameException The file name was found to be invalid. + */ + public static String checkFileName(String pFileName) { + if (pFileName != null && pFileName.indexOf('\u0000') != -1) { + // pFileName.replace("\u0000", "\\0") + final StringBuffer sb = new StringBuffer(); + for (int i = 0; i < pFileName.length(); i++) { + char c = pFileName.charAt(i); + switch (c) { + case 0: + sb.append("\\0"); + break; + default: + sb.append(c); + break; + } + } + throw new InvalidFileNameException(pFileName, + "Invalid file name: " + sb); + } + return pFileName; + } +} diff --git a/source/my/frame/src/frame/util/Util.java b/source/my/frame/src/frame/util/Util.java index 1ce487a..7ce8234 100644 --- a/source/my/frame/src/frame/util/Util.java +++ b/source/my/frame/src/frame/util/Util.java @@ -545,4 +545,23 @@ return calendar.get(Calendar.MONTH) + 1; } + public static String joinPath(String parent, String path) { + if (isEmptyStr(parent)) { + return path; + } + + parent = parent.replace("\\", "/"); + path = path.replace("\\", "/"); + + if ('/' == parent.charAt(parent.length() - 1)) { + parent = parent.substring(0, parent.length() - 1); + } + + if ('/' == path.charAt(0)) { + path = path.substring(1); + } + + return parent + "/" + path; + } + } -- Gitblit v1.8.0