Java tutorial
/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package net.duckling.ddl.web.controller; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.Principal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.duckling.ddl.common.DucklingProperties; import net.duckling.ddl.common.VWBContext; import net.duckling.ddl.common.VWBSession; import net.duckling.ddl.constant.Attributes; import net.duckling.ddl.constant.ELayout; import net.duckling.ddl.constant.KeyConstants; import net.duckling.ddl.constant.LynxConstants; import net.duckling.ddl.constant.SupportedFileForOfficeViewer; import net.duckling.ddl.service.authenticate.AuthenticationService; import net.duckling.ddl.service.authority.AuthorityService; import net.duckling.ddl.service.browselog.BrowseLogService; import net.duckling.ddl.service.file.FileVersion; import net.duckling.ddl.service.file.FileVersionService; import net.duckling.ddl.service.grid.IGridService; import net.duckling.ddl.service.resource.FolderPathService; import net.duckling.ddl.service.resource.IResourceService; import net.duckling.ddl.service.resource.Resource; import net.duckling.ddl.service.resource.ResourceOperateService; import net.duckling.ddl.service.team.Team; import net.duckling.ddl.service.team.TeamService; import net.duckling.ddl.service.tobedelete.File; import net.duckling.ddl.service.url.URLGenerator; import net.duckling.ddl.service.url.UrlPatterns; import net.duckling.ddl.service.user.AoneUserService; import net.duckling.ddl.service.user.AuthorizationCodeService; import net.duckling.ddl.util.Base64; import net.duckling.ddl.util.FileSizeUtils; import net.duckling.ddl.util.MimeType; import net.duckling.ddl.util.PdfStatus; import net.duckling.ddl.util.PlainTextHelper; import net.duckling.ddl.web.bean.AuthorizationCode; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import cn.cnic.cerc.dlog.client.DLogClient; import cn.cnic.cerc.dlog.client.WebLog; import cn.cnic.cerc.dlog.client.WebLogResolver; import cn.cnic.cerc.dlog.domain.LogBean; import cn.vlabs.commons.principal.UserPrincipal; import cn.vlabs.umt.oauth.AccessToken; import cn.vlabs.umt.oauth.UserInfo; import cn.vlabs.umt.oauth.common.exception.OAuthProblemException; /** * */ @Controller @RequestMapping("/{teamCode}/preview/{rid}") public class AttachmentController extends BaseController { private static final String PDF_UNSUPPORTED = "unsupported"; private static final String PDF_ORIGINAL = "original_pdf"; @Autowired private IResourceService resourceService; @Autowired private IGridService gridService; @Autowired private AuthorityService authorityService; @Autowired private ResourceOperateService resourceOperateService; @Autowired private URLGenerator urlGenerator; @Autowired private BrowseLogService browseLogService; @Autowired private FileVersionService fileVersionService; @Autowired private FolderPathService folderPathService; @Autowired private AoneUserService aoneUserService; @Autowired private TeamService teamService; @Autowired private AuthorizationCodeService authorizationCodeService; @Autowired private AuthenticationService authenticationService; @Autowired private DucklingProperties properties; @Autowired private WebLogResolver webLogResolver; private DLogClient dLogClient; protected static final Logger LOG = Logger.getLogger(AttachmentController.class); @RequestMapping public ModelAndView display(HttpServletRequest request, HttpServletResponse response, @PathVariable("rid") Integer rid) throws IOException, ServletException { String redirect = request.getParameter("redirect"); if (StringUtils.isEmpty(redirect)) { String url = request.getRequestURL().toString() + "?" + request.getQueryString() + "&redirect=redirect"; request.setAttribute("url", url); request.setAttribute("noHref", "no"); request.getRequestDispatcher("/jsp/aone/hash/dealHashRequest.jsp").forward(request, response); return null; } if (checkUserConflict(request, response)) { return null; } Resource resource = resourceService.getResource(rid); if (resource == null || resource.getTid() != VWBContext.getCurrentTid() || resource.isDelete()) { ModelAndView m = dealResourceRemove(request, resource); if (m != null) { return m; } notFound(request, response, true); return null; } ModelAndView mv = null; if (resource.isFile()) { mv = dealFile(request, response, resource); } else { notFound(request, response, true); return null; } mv.addObject("pageType", "list"); if (resource.isAvailable()) { mv.addObject("resourePath", getParentPath(resource)); } mv.addObject("teamUrl", urlGenerator.getURL(resource.getTid(), UrlPatterns.T_LIST, null, null)); mv.addObject("teamHome", urlGenerator.getURL(resource.getTid(), UrlPatterns.T_TEAM_HOME, null, null)); addMyTeam(request, mv); return mv; } /** * DDL?? * @param request * @return * @throws IOException * @throws ServletException */ private boolean checkUserConflict(HttpServletRequest request, HttpServletResponse resp) throws IOException, ServletException { String code = request.getParameter("code"); AuthorizationCode ac = authorizationCodeService.getCode(code); String uid = VWBSession.getCurrentUid(request); int tid = VWBContext.getCurrentTid(); boolean userConflict = true; if (ac != null && ac.isAvailable()) { if (!ac.getUid().equals(uid)) { updateLoginUser(request); } userConflict = false; } else { if (VWBSession.findSession(request).isAuthenticated()) { String auth = authorityService.getTeamAuthority(tid, uid); if ("forbid".equals(auth)) { String url = urlGenerator.getAbsoluteURL(UrlPatterns.LOGIN, null, null) + "?" + Attributes.REQUEST_URL + "=" + URLEncoder.encode(request.getRequestURL().toString(), "utf-8"); VWBSession.findSession(request).setAttribute(Attributes.REQUEST_URL, url); request.setAttribute("logout", "/system/logout"); request.getRequestDispatcher("/jsp/aone/tag/resousePreviewError.jsp").forward(request, resp); } else { userConflict = false; } } else { VWBSession.findSession(request).setAttribute(Attributes.REQUEST_URL, request.getRequestURL().toString()); resp.sendRedirect("/system/login"); } } return userConflict; } /** * DDL * @param request * @return */ private void updateLoginUser(HttpServletRequest request) { //?ddl authenticationService.invalidateSession(request); String code = request.getParameter("code"); AuthorizationCode ac = authorizationCodeService.getCode(code); try { AccessToken token = authorizationCodeService.umtAccessTokenValidate(ac.getAccessToken()); UserInfo u = token.getUserInfo(); UserPrincipal user = new UserPrincipal(u.getCstnetId(), getUserName(u.getCstnetId(), u), u.getCstnetId(), u.getType()); List<Principal> set = new ArrayList<Principal>(); set.add(user); VWBSession vwbsession = VWBSession.findSession(request); vwbsession.setPrincipals(set); request.getSession().setAttribute(Attributes.UMT_ACCESS_TOKEN, token.getAccessToken()); LOG.info("Successfully authenticated user:" + u.getCstnetId() + ";access_token:" + token); } catch (OAuthProblemException e) { LOG.error("", e); } } private String getUserName(String uid, UserInfo u) { String name = aoneUserService.getUserNameByID(uid); if (StringUtils.isEmpty(name)) { name = u.getTrueName(); } if (StringUtils.isEmpty(name)) { name = getNameFromEmail(uid); } return name; } private String getNameFromEmail(String uid) { int i = uid.indexOf("@"); if (i > 0) { return uid.substring(0, i); } else { return uid; } } /** * resource? * @param request * @param resource * @return */ private ModelAndView dealResourceRemove(HttpServletRequest request, Resource resource) { if (resource != null && LynxConstants.STATUS_DELETE.equals(resource.getStatus())) { String uid = VWBSession.getCurrentUid(request); VWBContext context = VWBContext.createContext(request, UrlPatterns.T_PAGE, resource.getRid(), LynxConstants.TYPE_PAGE); ModelAndView mv = layout(ELayout.LYNX_MAIN, context, "/jsp/aone/errors/resourceRemove.jsp"); boolean recoverFlag = false; if ((resource.getCreator().equals(uid) || isAdmin(uid, VWBContext.getCurrentTid()))) { if (resource.isFolder()) { recoverFlag = false; // ResourceDirectoryTrash t = resourceDirectoryTrashService.getResoourceTrash(resource.getRid()); // if(t!=null){ // recoverFlag = true; // } } else { recoverFlag = true; } } mv.addObject("recoverFlag", recoverFlag); mv.addObject("resource", resource); mv.addObject("teamCode", VWBContext.getCurrentTeamCode()); return mv; } else { return null; } } /** * ?? * @param request * @param response * @param resource * @return */ @WebLog(method = "preview", params = "rid,from") public ModelAndView dealFile(HttpServletRequest request, HttpServletResponse response, Resource resource) { VWBContext context = VWBContext.createContext(request, UrlPatterns.T_FILE, resource.getRid(), LynxConstants.TYPE_FILE); String uid = context.getCurrentUID(); int tid = context.getSite().getId(); int rid = resource.getRid(); ModelAndView mv = layout(".aone.attachment", context, "/jsp/aone/tag/attachmentView.jsp"); FileVersion currentVersion = getFileVersion(request, rid, tid); mv.addObject("resource", resource); Set<String> starmark = resource.getMarkedUserSet(); if (null != starmark && starmark.contains(context.getCurrentUID())) { mv.addObject("starmark", true); } else { mv.addObject("starmark", false); } currentVersion.setEditor(aoneUserService.getUserNameByID(currentVersion.getEditor())); mv.addObject("deleteFileURL", urlGenerator.getURL(tid, UrlPatterns.T_FILE, rid + "", "func=moveToTrash&bid=0")); mv.addObject("validateURL", urlGenerator.getURL(tid, UrlPatterns.T_FILE, rid + "", "func=removeValidate")); mv.addObject("cid", currentVersion.getClbId()); mv.addObject("curVersion", currentVersion); mv.addObject("latestVersion", currentVersion.getVersion()); mv.addObject("sizeShort", FileSizeUtils.getFileSize(currentVersion.getSize())); mv.addObject("fileExtend", getFileExtend(currentVersion.getTitle(), currentVersion.getSize())); String downType = "type=doc"; downType += "&version=" + currentVersion.getVersion(); mv.addObject("downloadURL", urlGenerator.getURL(tid, "download", Integer.toString(rid), downType)); gridService.clickItem(uid, tid, rid, LynxConstants.TYPE_FILE); String strFilename = currentVersion.getTitle(); int index = strFilename.lastIndexOf('.'); fileOnlineShow(mv, currentVersion, strFilename, index); browseLogService.resourceVisited(tid, rid, uid, context.getCurrentUserName(), LynxConstants.TYPE_FILE); String enableDConvert = context.getContainer().getProperty(KeyConstants.DCONVERT_SERVICE_ENABLE); mv.addObject("enableDConvert", Boolean.valueOf(enableDConvert)); mv.addObject("uid", context.getCurrentUID()); mv.addObject("isOffice", SupportedFileForOfficeViewer.isOfficeFile(currentVersion.getTitle())); mv.addObject("isPreview", isPreview(currentVersion)); mv.addObject("clbPreviewUrl", properties.get("duckling.clb.url") + "/wopi/p?accessToken=" + getClbToken(currentVersion.getClbId(), currentVersion.getClbVersion(), properties)); LOG.info("uid:" + uid + " preview resource rid=" + rid); addPreviewLog(request); return mv; } private void addPreviewLog(HttpServletRequest request) { try { DLogClient client = getDLogClient(); LogBean aLog = new LogBean(); aLog.setHost(request.getLocalAddr()); aLog.setMethod("preview"); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = format.format(new Date()); aLog.setTime(time); Map<String, String> params = webLogResolver.buildFixedParameters(request); params.put("from", request.getParameter("from")); aLog.setOption(params); LinkedList<LogBean> ls = new LinkedList<LogBean>(); ls.add(aLog); client.sendLogData(client.prepareData(ls)); } catch (Exception e) { LOG.error("", e); } } private boolean isPreview(FileVersion fv) { if (fv.getTitle().toLowerCase().endsWith("pdf")) { return true; } return SupportedFileForOfficeViewer.isSupportedFile(fv.getTitle()) && fv.getSize() < 52428800; } private FileVersion getFileVersion(HttpServletRequest request, int rid, int tid) { String from = request.getParameter("from"); if ("web".equals(from)) { String version = request.getParameter("version"); if (StringUtils.isEmpty(version)) { return fileVersionService.getLatestFileVersion(rid, tid); } else { int ver = Integer.parseInt(version); return fileVersionService.getFileVersion(rid, tid, ver); } } else { //1 return fileVersionService.getFileVersion(rid, tid, 1); } } private List<Resource> getParentPath(Resource resource) { int pRid = resource.getBid(); if (pRid == 0) { return Collections.emptyList(); } List<Resource> result = folderPathService.getResourcePath(pRid); if (result == null) { return Collections.emptyList(); } return result; } public void fileOnlineShow(ModelAndView mv, FileVersion currentVersion, String strFilename, int index) { String strFileType = null; if (index != -1 && strFilename.length() > (index + 1)) { strFileType = strFilename.substring(index + 1); } if (null != strFileType) { strFileType = strFileType.toLowerCase(); String pdfstatus = PdfStatus.SOURCE_NOT_FOUND.toString();// PDF? boolean supported = SupportedFileForOfficeViewer.isSupported(strFileType); if ("pdf".equals(strFileType)) { pdfstatus = PDF_ORIGINAL; } else if (supported) { pdfstatus = resourceOperateService.queryPdfStatus(currentVersion.getClbId(), "" + currentVersion.getClbVersion()); } else { pdfstatus = PDF_UNSUPPORTED;// ?? } if (pdfstatus == PDF_UNSUPPORTED && isSupportedFileType(strFileType)) { // ?? strFileType = "img"; } mv.addObject("strFileType", PlainTextHelper.convert2BrushClassFileType(strFileType)); mv.addObject("pdfstatus", pdfstatus); mv.addObject("supported", supported); } } private boolean isSupportedFileType(String fileType) { if (null == fileType || "".equals(fileType)) { return false; } if (SupportedFileForOfficeViewer.isSupported(fileType)) { return true; } if (File.isPictureFileTypeForSearch(fileType)) { return true; } return false; } private String getFileExtend(String filename, long size) { if (MimeType.isImage(filename)) { return "IMAGE"; } else if (PlainTextHelper.isSupported(MimeType.getSuffix(filename)) && size < LynxConstants.MAXFILESIZE_CODEREVIEW) {// ?? return "TEXT"; } return "FILE"; } private boolean isAdmin(String user, int tid) { if (user == null || user.length() == 0) { return false; } return Team.AUTH_ADMIN.equals(authorityService.getTeamAuthority(tid, user)); } private ModelAndView addMyTeam(HttpServletRequest request, ModelAndView mv) { VWBContext context = getVWBContext(request); int myTeamId = teamService.getPersonalTeamNoCreate(context.getCurrentUID()); String myTeamCode = teamService.getTeamNameFromEmail(context.getCurrentUID()); mv.addObject("myTeamId", myTeamId); mv.addObject("myTeamCode", myTeamCode); return mv; } private VWBContext getVWBContext(HttpServletRequest request) { return VWBContext.createContext(request, UrlPatterns.T_VIEW_FILE); } public static String getClbToken(int docId, int version, Properties properties) { HttpClient client = getHttpClient(); PostMethod method = new PostMethod(getClbTokenUrl(properties)); method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8"); method.addParameter("appname", properties.getProperty("duckling.clb.aone.user")); method.addParameter("docid", docId + ""); method.addParameter("version", version + ""); try { method.addParameter("password", Base64.encodeBytes(properties.getProperty("duckling.clb.aone.password").getBytes("utf-8"))); } catch (IllegalArgumentException | UnsupportedEncodingException e) { } try { int status = client.executeMethod(method); String responseString = null; if (status < 400) { responseString = method.getResponseBodyAsString(); org.json.JSONObject j = new org.json.JSONObject(responseString); Object st = j.get("status"); if ("failed".equals(st)) { LOG.error("?clb token?"); return null; } else { return j.get("pf").toString(); } } else { LOG.error("STAUTS:" + status + ";MESSAGE:" + responseString); } } catch (HttpException e) { LOG.error("", e); } catch (IOException e) { LOG.error("", e); } catch (ParseException e) { LOG.error("", e); } return null; } private static String getClbTokenUrl(Properties properties) { return properties.getProperty("duckling.clb.url") + "/wopi/fetch/accessToken"; } private static HttpClient httpClient; private static HttpClient getHttpClient() { if (httpClient == null) { synchronized (LOGGER) { if (httpClient == null) { httpClient = new HttpClient(); httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); } } } return httpClient; } private DLogClient getDLogClient() { if (dLogClient == null) { synchronized (LOGGER) { if (dLogClient == null) { dLogClient = new DLogClient(properties.getProperty("duckling.dlog.application.name"), properties.getProperty("duckling.dlog.server")); } } } return dLogClient; } }