网络会议openmeetings下的openmeetings-util文件分析3

2021SC@SDUSC

上篇文章主要对模块openmeetins-util下src/main中的crypt文件里面的六个类进行了分析,文件的主要功能即实现对字符串的哈希编码形成哈希字符串返回,并用来实现加密功能。接下来将继续分析util文件下的其他类。该篇文章将分析src/main下的mail文件夹下的类。

目录

mail文件夹

ByteArrayDataSourse类

IcalHandler类

MailUtil类

总结


mail文件夹

首先看mail文件下的类:

总共只有三个类,分别是ByteArrayDataSourse、IcalHandler、MailUtil类来实现创建数据源、对会议日历的处理、以及判断地址是否有效。

ByteArrayDataSourse类

public class ByteArrayDataSource implements DataSource {
   private byte[] data; // data

   private String type; // content-type

   public ByteArrayDataSource(InputStream is, String type) {
      this.type = type;
      try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
         int ch;

         while ((ch = is.read()) != -1) {
            os.write(ch);
         }
         data = os.toByteArray();
      } catch (IOException ioex) {
         //no-op
      }
   }

   public ByteArrayDataSource(byte[] data, String type) {
      this.data = data;
      this.type = type;
   }

   public ByteArrayDataSource(String data, String type) {
      this.data = data.getBytes(UTF_8);
      this.type = type;
   }

   @Override
   public InputStream getInputStream() throws IOException {
      if (data == null)
         throw new IOException("no data");
      return new ByteArrayInputStream(data);
   }

   @Override
   public OutputStream getOutputStream() throws IOException {
      throw new IOException("cannot do this");
   }

   @Override
   public String getContentType() {
      return type;
   }

   @Override
   public String getName() {
      return "dummy";
   }
}

这个类ByteArrayDataSourse实现了DataSourse接口,并实现了它的方法。

DataSourse这是一个工厂对象,用于提供到此 DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。

实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。

使用Spring Boot时,默认情况下,配置DataSource非常容易。Spring Boot会自动为我们配置好一个DataSource。如果在application.yml中指定了spring.datasource的相关配置,Spring Boot就会使用该配置创建一个DataSource。如果在application.yml中没有指定任何spring.datasource的相关配置,Spring Boot会在classpath中搜索H2、hsqldb等内存数据库的jar包,如果找到了,就会自动配置一个内存数据库的DataSource,所以,我们只要引入jar包即可。

该类里面定义了一个byte类型的数组data,以及String类型的type,分别表示数据和内容类型。首先是第一个方法是其带参数的构造方法,接收的参数为InputStream类对象is和String类型变量type,是从输入流创建数据源。第二个构造方法是接收一个byte数组类型对象data和String类型变量type,是从字节数组创建数据源。第三个构造方法是接收一个String类型变量data和String类型变量type,是从一个字符串创建一个数据源。然后实现了上述接口类DataSource里的四个get方法,不需要分析。

IcalHandler类

public class IcalHandler {
   private static final Logger log = Red5LoggerFactory.getLogger(IcalHandler.class, getWebAppRootKey());
   static {
      System.setProperty("net.fortuna.ical4j.timezone.update.enabled", "false");
      System.setProperty("net.fortuna.ical4j.timezone.cache.impl", "net.fortuna.ical4j.util.MapTimeZoneCache");
   }

   /** ICal instance */
   private final Calendar icsCalendar;

   /** Creation of a new Event */
   public static final Method ICAL_METHOD_REQUEST = Method.REQUEST;
   public static final Method ICAL_METHOD_CANCEL = Method.CANCEL;
   public static final Method ICAL_METHOD_REFRESH = Method.REFRESH;

   public IcalHandler(Method method) {
      log.debug("Icalhandler method type : " + method);

      icsCalendar = new Calendar();
      icsCalendar.getProperties().add(new ProdId("-//Events Calendar//iCal4j 1.0//EN"));
      icsCalendar.getProperties().add(Version.VERSION_2_0);
      icsCalendar.getProperties().add(CalScale.GREGORIAN);
      icsCalendar.getProperties().add(method);
   }

   // ---------------------------------------------------------------------------------------
   public String addNewMeeting(Date startDate, Date endDate, String name,
         List<Map<String, String>> attendees, String description,
         Map<String, String> organizer, String uid, String javaTzId)
   {

      TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();

      TimeZone timeZone = registry.getTimeZone(javaTzId);
      if (timeZone == null) {
         throw new NoSuchElementException("Unable to get time zone by id provided: " + javaTzId);
      }

      DateTime start = new DateTime(startDate);
      start.setTimeZone(timeZone);
      DateTime end = new DateTime(endDate);
      end.setTimeZone(timeZone);

      VEvent meeting = new VEvent(start, end, name);

      meeting.getProperties().add(new Description(description));
      meeting.getProperties().add(new Sequence(0));
      meeting.getProperties().add(new Location(""));
      meeting.getProperties().add(Transp.OPAQUE);

      // generate unique identifier (if not submitted)
      Uid ui;
      if (Strings.isEmpty(uid)) {
         ui = new Uid(UUID.randomUUID().toString());
         log.debug("Generating Meeting UID : " + ui.getValue());
      } else {
         ui = new Uid(uid);
         log.debug("Using Meeting UID : " + ui.getValue());
      }

      meeting.getProperties().add(ui);

      for (Map<String, String> att : attendees) {
         Attendee uno = new Attendee(URI.create(att.get("uri")));
         String chair = att.get("chair");
         uno.getParameters().add("0".equals(chair) ? Role.REQ_PARTICIPANT : Role.CHAIR);
         uno.getParameters().add(new Cn(att.get("cn")));
         meeting.getProperties().add(uno);
      }

      Organizer orger = new Organizer(URI.create(organizer.get("uri")));
      orger.getParameters().add(new Cn(organizer.get("cn")));

      meeting.getProperties().add(orger);

      icsCalendar.getComponents().add(timeZone.getVTimeZone());
      icsCalendar.getComponents().add(meeting);

      return ui.getValue();
   }

   public Map<String, String> getAttendeeData(String emailAdress, String displayName, boolean chair) {
      Map<String, String> oneRecord = new HashMap<>();
      oneRecord.put("uri", "mailto:" + emailAdress);
      oneRecord.put("cn", displayName);
      oneRecord.put("chair", chair ? "1" : "0");

      return oneRecord;
   }

   public void writeDataToFile(String _filerPath) throws Exception {
      String filerPath = _filerPath.endsWith(".ics") ? _filerPath
            : String.format("%s.ics", _filerPath);

      try (FileOutputStream fout = new FileOutputStream(filerPath)) {
         CalendarOutputter outputter = new CalendarOutputter();
         outputter.output(icsCalendar, fout);
      }
   }

   public byte[] getIcalAsByteArray() throws Exception {
      ByteArrayOutputStream bout = new ByteArrayOutputStream();
      CalendarOutputter outputter = new CalendarOutputter();
      outputter.output(icsCalendar, bout);
      return bout.toByteArray();
   }

   public String getICalDataAsString() {
      return icsCalendar.toString();
   }
}

类IcalHandler首先利用Red5LoggerFactory工厂类创建一个Logger日志类对象log,方便打印日志,利于测试过程中的调试。IcalHandler是对日历和会议进行处理的一个类,Ical是指互联网日历。定义了一个常量Calendar类对象 icsCalendar 实例,创建几个新的事件,包括ICAL_METHOD_REQUEST、ICAL_METHOD_CANCEL、ICAL_METHOD_REFRESH,主要用于在程序运行状态中,动态地获取方法信息。

构造函数接收Method类对象参数,将该参数记录在日志里面,然后初始化icsCalendar对象,调用getProperties()为它设置属性,例如版本信息,id,规模和method。

然后addNewMeeting()方法接收几个参数,startDate和endDate为使用标准时区,name为会议名字,attendees为参与会议的人列表,description为对这个会议的描述,oganizer为会议组织者,uid为会议号(传入的时候可能为空),javaTzId是所有者的java时区ID,返回是是该会议的id号。该方法即是添加一个会议,设置会议的一些属性。

然后getAttendeeData()方法:使用此函数为添加会议生成与会者建立一个有效的记录。接收的参数,emailAdress是参会者的地址,displayName为参会者的名字,chair是当前组织者。返回的为一个记录Map。

然后writeDataToFile()方法:将iCal写入文件,参数_filerPath是“*.ics”文件的路径,该方法会抛出异常以防在写入文件时发生错误。

接下来的getIcalAsByteArray()方法:获取IcalBody作为ByteArray,返回以字节格式显示的ICS日历,该方法会抛出异常以防在写入字节数组时发生错误。

最后的getICalDataAsString():以字符串形式检索数据,返回类变量icsCalendar的字符串形式。

MailUtil类

public class MailUtil {
   private MailUtil() {}

   public static boolean isValid(String email) {
      if (Strings.isEmpty(email)) {
         return false;
      }
      Validatable<String> eml = new Validatable<>(email);
      RfcCompliantEmailAddressValidator.getInstance().validate(eml);
      return eml.isValid();
   }
}

类MailUtil里面只有一个方法即isValid(String email),即判断传入的参数email是否有效。

如果为空则为无效,导入import org.apache.wicket.validation.Validatable;依赖,利用validate()方法进行数据校验。 RfcCompliantEmailAddressValidator是一个测试套件,This test suite comes from Dominic Sayers and is a mix of RFC examples and examples from other validators.

The test suite is currently allowing addresses that are unroutable on the public Internet, such as first.last@example.123. This behavior is disabled by default, but can be switched on; the tests are run in both modes for comparison.(这个测试套件来自Dominic Sayers,它混合了RFC示例和来自其他验证器的示例。测试套件目前允许在公共互联网上不可路由的地址,例如first.last@example.123。这种行为在默认情况下是禁用的,但可以打开;测试在两种模式下运行,以便进行比较。)

总结

本文对src/main/mail文件下的三个类进行了分析。之后将继续对main文件下的类和代码进行分析。下一篇文章将对src/main/process下的类进行分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值