栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2021SC@SDUSC 软件工程应用与实践——OpenMeetings项目分析(四)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021SC@SDUSC 软件工程应用与实践——OpenMeetings项目分析(四)

2021SC@SDUSC

软件工程应用与实践——OpenMeetings项目分析(四):

承接上周任务,本周继续进行util包下的baseWebService的各派生类的源码分析;

CalendarWebService.java

首先分析的是CalendarWebService.java,先贴上源码:

@Service("calendarWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.CalendarWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/calendar")
public class CalendarWebService extends baseWebService {
	private static final Logger log = Red5LoggerFactory.getLogger(CalendarWebService.class, getWebAppRootKey());

	private static AppointmentDao getDao() {
		return getBean(AppointmentDao.class);
	}
	
	@GET
	@Path("/{start}/{end}")
	public List range(@QueryParam("sid") @WebParam(name="sid") String sid
			, @PathParam("start") @WebParam(name="start") Calendar start
			, @PathParam("end") @WebParam(name="end") Calendar end
			)
	{
		log.debug("range : startdate - {} , enddate - {}"
				, start == null ? "" : start.getTime()
				, end == null ? "" : end.getTime());
		return performCall(sid, User.Right.Room
				, sd -> AppointmentDTO.list(getDao().getInRange(sd.getUserId(), start.getTime(), end.getTime())));
	}

	
	@GET
	@Path("/{userid}/{start}/{end}")
	public List rangeForUser(
			@QueryParam("sid") @WebParam(name="sid") String sid
			, @PathParam("userid") @WebParam(name="userid") long userid
			, @PathParam("start") @WebParam(name="start") Calendar start
			, @PathParam("end") @WebParam(name="end") Calendar end
			)
	{
		log.debug("rangeForUser : startdate - {} , enddate - {}"
				, start == null ? "" : start.getTime()
				, end == null ? "" : end.getTime());
		return performCall(sid, User.Right.Soap
				, sd -> AppointmentDTO.list(getDao().getInRange(userid, start.getTime(), end.getTime())));
	}

	
	@GET
	@Path("/next")
	public AppointmentDTO next(@QueryParam("sid") @WebParam(name="sid") String sid) {
		return performCall(sid, User.Right.Room, sd -> {
			Appointment a = getDao().getNext(sd.getUserId(), new Date());
			return a == null ? null : new AppointmentDTO(a);
		});
	}

	
	@GET
	@Path("/next/{userid}")
	public AppointmentDTO nextForUser(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("userid") @WebParam(name="userid") long userid) {
		return performCall(sid, User.Right.Soap, sd -> {
			Appointment a = getDao().getNext(userid, new Date());
			return a == null ? null : new AppointmentDTO(a);
		});
	}

	
	@GET
	@Path("/room/{roomid}")
	public AppointmentDTO getByRoom(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("roomid") @WebParam(name="roomid") long roomid) {
		return performCall(sid, User.Right.Room, sd -> {
			Appointment a = getDao().getByRoom(sd.getUserId(), roomid);
			return a == null ? null : new AppointmentDTO(a);
		});
	}

	
	@GET
	@Path("/title/{title}")
	public List getByTitle(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("title") @WebParam(name="title") String title) {
		return performCall(sid, User.Right.Room, sd -> AppointmentDTO.list(getDao().searchByTitle(sd.getUserId(), title)));
	}

	
	@WebMethod
	@POST
	@Path("/")
	public AppointmentDTO save(@QueryParam("sid") @WebParam(name="sid") String sid, @FormParam("appointment") @WebParam(name="appointment") AppointmentDTO appointment) {
		//Seems to be create
		log.debug("save SID: {}", sid);

		UserDao userDao = getUserDao();
		return performCall(sid, sd -> {
				User u = userDao.get(sd.getUserId());
				if (!AuthLevelUtil.hasUserLevel(u.getRights())) {
					log.error("save: not authorized");
					return false;
				}
				return AuthLevelUtil.hasWebServiceLevel(u.getRights())
						|| appointment.getOwner() == null
						|| appointment.getOwner().getId().equals(u.getId());
			}, sd -> {
				User u = userDao.get(sd.getUserId());
				AppointmentDao dao = getDao();
				Appointment a = appointment.get(userDao, getFileDao(), dao, u);
				if (a.getRoom().getId() != null) {
					if (a.getRoom().isAppointment()) {
						a.getRoom().setIspublic(false);
					} else {
						a.setRoom(getRoomDao().get(a.getRoom().getId()));
					}
				}
				return new AppointmentDTO(dao.update(a, u.getId()));
			});
	}

	
	@DELETE
	@Path("/{id}")
	public ServiceResult delete(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("id") @WebParam(name="id") Long id) {
		AppointmentDao dao = getDao();
		Appointment a = dao.get(id);
		return performCall(sid, sd -> {
				Set rights = getRights(sd.getUserId());
				if (AuthLevelUtil.hasWebServiceLevel(rights) || AuthLevelUtil.hasAdminLevel(rights)) {
					return true;
					// fine
				}
				if (AuthLevelUtil.hasUserLevel(rights) && a.getOwner().getId().equals(sd.getUserId())) {
					return true;
				}
				return false;
			}, sd -> {
				if (a == null) {
					throw new ServiceException("Bad id");
				}
				dao.delete(a, sd.getUserId());
				return new ServiceResult("Deleted", Type.SUCCESS);
			});
	}
}

根据注释可以看出,CalendarWebService类包含了创建编辑和删除指定日期的会议的方法,因此主要功能是预定会议时日期的添加删除与编辑等操作;先观察IDEA生成的关于此类的结构图,如下:

包括了数个公有方法,一个私有方法,以及一个私有数据log;

getDao方法:返回AppointmentDao(db.dao.caldener下的一个实体类)调用了其父类的getBean方法,传入AppointmentDao的class属性返回一个bean;

range方法:根据方法的注释,这个方法需要三个参数,SID,start,end,返回一个指定范围的AppointmentDTo的列表,首先利用org.slf4j.Logger 的log对象调用debug方法对开始日期以及结束日期进行非空判断,然后调用父类的performcall方法返回一个列表;

rangeForuser方法:需要四个参数,用户的sid(此用户必须是已经登录的),userid数值型的用户标识符,开始时间start以及结束时间end,同样地返回一个AppointmentDTO的列表;这两个方法都用到了Appointment类的一个getInrange方法,因此对这个方法也稍作分析,同样需要用户id,开始时间以及结束时间,利用javax.persistence.EntityManager 的对象进行创建队列,然后按照参数要求将appointment对象创建出来添加到新的一个列表,最后将这个列表返回;

next方法:获取用户id为sid的用户的下一个日期事件,接收一个sid的参数,返回一个calendar event对象即AppointmentDTO类型;

nextForUser方法:参数为sid和userid,分别为当前登录用户的id以及要进行事件加载的人的id,返回的同样是next Calendar event,下一个日期事件

getByRoom方法:此方法作用为按房间ID加载日期事件,接收参数为sid,roomid即要进行会议的房间标号,返回一个AppointmentDTO;

getByTitle方法:搜索当前用户(用户id为sid)的日历事件,接收参数为sid以及title(搜索的标题),返回的是一个AppointmentDTO类型得列表;

save方法:见名知意,保存,此方法用来保存日历事件,接收参数为sid以及appointment对象(AppointmentDTO),返回值为AppointmentDTO;

同时方法内使用了lambda表达式和函数式接口Predicate和Function,在上一周分析时有提到,举个简单的例子,方法中的performcall里的两个参数sd ->{}就是lamda表达式,举个简单的例子,consumer就是一个函数式接口:

Consumer consumer = s -> System.out.println(s);
consumer.accept("Java3y");

delete方发:同上,delete方法是用于删除日历事件的 如果给定的 sid 来自管理员或 Web 服务用户,则该用户可以删除任何约会。 如果 sid 分配给普通用户,则他只能删除同时也是约会所有者/创建者的约会,接收参数为经过身份验证的用户sid以及待删除的会议id,返回一个带有结果类型的ServiceResult;

Constants.java

constants的意思是常量,因此本类主要定义一些常量;

先贴上源码:

package org.apache.openmeetings.webservice;

public class Constants {
	public static final String TNS = "http://webservice.openmeetings.apache.org/";
	public static final String USER_SERVICE_NAME = "org.apache.openmeetings.webservice.UserWebService";
	public static final String USER_SERVICE_PORT_NAME = "UserService";

	private Constants() {}
}

定义三个静态字符串类型的常量TNSUSER_SERVICE_NAME和USER_SERVICE_PORT_NAME

ErrorWebService.java

先附上源代码:

package org.apache.openmeetings.webservice;

import static org.apache.openmeetings.util.OpenmeetingsVariables.getWebAppRootKey;
import static org.apache.openmeetings.webservice.Constants.TNS;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.cxf.feature.Features;
import org.apache.openmeetings.db.dao.label.LabelDao;
import org.apache.openmeetings.db.dto.basic.ServiceResult;
import org.apache.openmeetings.db.dto.basic.ServiceResult.Type;
import org.apache.openmeetings.db.entity.server.Sessiondata;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;


@Service("errorWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.ErrorWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/error")
public class ErrorWebService extends baseWebService {
	private static final Logger log = Red5LoggerFactory.getLogger(ErrorWebService.class, getWebAppRootKey());

	
	@WebMethod
	@GET
	@Path("/{key}/{lang}")
	public ServiceResult get(@WebParam(name="key") @PathParam("key") String key, @WebParam(name="lang") @PathParam("lang") long lang) {
		try {
			String evalue = LabelDao.getString(key, lang);
			return new ServiceResult(evalue, Type.SUCCESS);
		} catch (Exception err) {
			log.error("[get] ", err);
		}
		return null;
	}

	@WebMethod
	@POST
	@Path("/report/")
	public void report(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="message") @QueryParam("message") String message) {
		if (sid != null && message != null) {
			Sessiondata sd = check(sid);
			if (sd.getId() != null) {
				log.error("[CLIENT MESSAGE] " + message);
			}
		}
	}
}

ErrorWebService类继承自basewebservice,包含获取本地化错误的方法;代码量较少,从idea观察其结构,如图:

包含一个成员变量log和之前的类一样,用了工厂模式,log是由Red5LoggerFactory对象调勇getLogger方法生产的;同时包含了两个共有方法get以及report;

get方法:加载一个错误对象。 如果一个方法返回一个负结果,它是一个错误 ID,它需要一个 languageId 来指定你想用哪种语言显示/读取错误消息。 英语有 Language-ID 之一,不同的语言可以根据语言列表指定;接收参数为key,错误的键,以及lang是语言的id标识符;返回一个ServiceResult的类型得代码错误;

report方法:检测有没有出现异常,检测到异常,就调用log对象的error方法将异常的message发送;

FileWebService.java
package org.apache.openmeetings.webservice;

@Service("fileWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.FileWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/file")
public class FileWebService extends baseWebService {
	private static final Logger log = Red5LoggerFactory.getLogger(FileWebService.class, getWebAppRootKey());

	
	@DELETE
	@Path("/{id}")
	public ServiceResult delete(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("id") @WebParam(name="id") Long id) {
		FileItemDao dao = getFileDao();
		FileItem f = dao.get(id);
		return performCall(sid, sd -> {
				Long userId = sd.getUserId();
				Set rights = getRights(userId);
				return AuthLevelUtil.hasWebServiceLevel(rights)
					|| (AuthLevelUtil.hasUserLevel(rights) && userId.equals(f.getOwnerId()));
			}
			, sd -> {
				if (f == null) {
					return new ServiceResult("Bad id", Type.ERROR);
				}
				dao.delete(f);
				return new ServiceResult("Deleted", Type.SUCCESS);
			});
	}

	
	@DELETE
	@Path("/{externaltype}/{externalid}")
	public ServiceResult deleteExternal(
			@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="externaltype") @PathParam("externaltype") String externalType
			, @WebParam(name="externalid") @PathParam("externalid") String externalId
			)
	{
		return performCall(sid, User.Right.Soap, sd -> {
			FileItemDao dao = getFileDao();
			FileItem f = dao.get(externalId, externalType);
			dao.delete(f);
			return new ServiceResult("Deleted", Type.SUCCESS);
		});
	}

	
	@WebMethod
	@POST
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	@Path("/")
	public FileItemDTO add(@WebParam(name="sid") @QueryParam("sid") String sid
			, @Multipart(value = "file", type = MediaType.APPLICATION_JSON) @WebParam(name="file") FileItemDTO file
			, @Multipart(value = "stream", type = MediaType.APPLICATION_OCTET_STREAM, required = false) @WebParam(name="stream") InputStream stream
			)
	{
		return performCall(sid, User.Right.Soap, sd -> {
			FileItem f = file == null ? null : file.get();
			if (f == null || f.getId() != null) {
				throw new ServiceException("Bad id");
			}
			f.setInsertedBy(sd.getUserId());
			if (stream != null) {
				try {
					ProcessResultList result = getBean(FileProcessor.class).processFile(f, stream);
					if (result.hasError()) {
						throw new ServiceException(result.getLogMessage());
					}
				} catch (Exception e) {
					throw new ServiceException(e.getMessage());
				}
			} else {
				f = getFileDao().update(f);
			}
			return new FileItemDTO(f);
		});
	}

	
	@WebMethod
	@GET
	@Path("/{externaltype}")
	public List getAllExternal(@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="externaltype") @PathParam("externaltype") String externalType
			)
	{
		log.debug("getAllExternal::externalType {}", externalType);
		return performCall(sid, User.Right.Soap, sd -> {
			FileItemDao dao = getFileDao();
			return FileItemDTO.list(dao.getExternal(externalType));
		});
	}

	
	@WebMethod
	@GET
	@Path("/room/{id}")
	public FileExplorerObject getRoom(@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="id") @PathParam("id") long roomId
			)
	{
		log.debug("getRoom::roomId {}", roomId);
		return performCall(sid, User.Right.Soap, sd -> {
			FileItemDao dao = getFileDao();
			FileExplorerObject fileExplorerObject = new FileExplorerObject();

			// Home File List
			List fList = dao.getByOwner(sd.getUserId());
			fileExplorerObject.setUser(fList, dao.getSize(fList));

			// Public File List
			List rList = dao.getByRoom(roomId);
			fileExplorerObject.setRoom(rList, dao.getSize(rList));

			return fileExplorerObject;
		});
	}

	
	@WebMethod
	@GET
	@Path("/room/{id}/{parent}")
	public List getRoomByParent(@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="id") @PathParam("id") long roomId
			, @WebParam(name="parent") @PathParam("parent") long parentId
			)
	{
		log.debug("getRoomByParent {}", parentId);
		return performCall(sid, User.Right.Room, sd -> {
			FileItemDao dao = getFileDao();
			List list;
			if (parentId < 0) {
				if (parentId == -1) {
					list = dao.getByOwner(sd.getUserId());
				} else {
					list = dao.getByRoom(roomId);
				}
			} else {
				list = dao.getByParent(parentId);
			}
			return FileItemDTO.list(list);
		});
	}

	
	@WebMethod
	@POST
	@Path("/rename/{id}/{name}")
	public FileItemDTO rename(@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="id") @PathParam("id") long id
			, @WebParam(name="name") @PathParam("name") String name)
	{
		log.debug("rename {}", id);
		return performCall(sid, User.Right.Soap, sd -> {
			FileItem f = getFileDao().rename(id, name);
			return f == null ? null : new FileItemDTO(f);
		});
	}

	
	@WebMethod
	@POST
	@Path("/move/{roomid}/{id}/{parentid}")
	public FileItemDTO move(@WebParam(name="sid") @QueryParam("sid") String sid
			, @WebParam(name="id") @PathParam("id") long id
			, @WebParam(name="roomid") @PathParam("roomid") long roomId
			, @WebParam(name="parentid") @PathParam("parentid") long parentId)
	{
		log.debug("move {}", id);
		return performCall(sid, User.Right.Soap, sd -> {
			FileItem f = getFileDao().move(id, parentId, sd.getUserId(), roomId);
			return f == null ? null : new FileItemDTO(f);
		});
	}
}

同上,先查看类的结构:

FileWebService.java继承自basewebservice包含将文件导入和上传到会议室的文件部分和任何用户的个人驱动器的方法;主要包括8个公有方法和一个成员变量;

delete方法:根据id删除已经上传的文件或者文件夹,接收参数为sid登录用户的标识以及欲删除的文件的id,返回的结果类型为ServiceResult;

deleteExternal方法:按外部 ID 和类型删除文件,接收参数为:sid – 用户的 SID。 此 SID 必须标记为已登录,externalType – 外部类型,externalId – 文件或文件夹的 od,返回值是带有结果类型的ServiceResult

add方法:此方法主要目的是将文件添加到会议中,要将文件夹添加到私有驱动器,请将 parentId = 0 和 isOwner 设置为 1/true 并将 externalUserId/externalUserType 设置为有效用户,接收参数为sid – 用户的 SID, 此 SID 必须标记为已登录,file – 要添加的文件,stream – 要添加的文件(流类型),返回一个FileItemDTO;

getAllExternal方法:按外部类型获取所有文件,接收形参:sid – 用户的 SID。 此 SID 必须标记为已登录,externalType – 文件列表的外部类型返回值:给定外部类型的文件列表‘;

getRoom方法:此方法主要目的是通过给定房间获取文件资源管理器对象,接收形参:sid – 用户的 SID。 此 SID 必须标记为已登录,roomId – 房间 ID,返回值:给定房间的文件资源管理器对象

getRoomByParent方法:此方法主要目的是通过父获取FileItemDTO列表,接收形参:sid – SID 用户的 SID。 此 SID 必须标记为已登录,roomId – 房间 ID,parentId – 父文件夹 ID返回值:文件资源管理器项目列表

rename方法:此方法主要目的是更新文件或文件夹名称,接收形参:sid – SID 用户的 SID。 此 SID 必须标记为已登录,id – 文件或文件夹 ID,名称 - 新文件或文件夹名称返回值:结果文件对象

move方法:此方法主要目的是移动文件或文件夹,接收形参:sid – SID 用户的 SID。 此 SID 必须标记为已登录,id – 要移动的当前文件或文件夹 ID,roomId – 这个文件需要移动的房间,parentId – 新的父文件夹 ID,返回值:结果文件对象

总结:这几个webservice类均继承自basewebservice,作用为通过调用被注入的多个dao对象进行对不同事务的控制与管理,完成各种操作;这周没能分析完全util包下的所有派生类,下周先把剩下的派生类分析完,搞清楚每个类负责控制管理什么服务,然后根据情况开始web包下的分析。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号