Package org.jnode.pointchecker

Source Code of org.jnode.pointchecker.PointCheckerModule

/*
* Licensed to the jNode FTN Platform Develpoment Team (jNode Team)
* under one or more contributor license agreements.
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. 
* The jNode Team 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 org.jnode.pointchecker;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import jnode.event.IEvent;
import jnode.ftn.FtnTools;
import jnode.ftn.types.FtnAddress;
import jnode.logger.Logger;
import jnode.module.JnodeModule;
import jnode.module.JnodeModuleException;
import jnode.ndl.FtnNdlAddress;
import jnode.ndl.NodelistScanner;

/**
* Для NPK и RPK
*
* Поскольку я сам NPK :)
*
* @author kreon
*
*/
public class PointCheckerModule extends JnodeModule {

  private final static String CONFIG_MULTI = "multi";
  private final static String CONFIG_CORRECT = "correct";
  private final static String CONFIG_INCORRECT = "incorrect";
  private final static String CONFIG_NAME = "name";
  private final static String CONFIG_ZIP = "zip";
  private final static String CONFIG_SEG = "seg";
  private final static String CONFIG_BOSS = "boss";
  private final static String CONFIG_SCANDELAY = "scandelay";

  private static final Logger logger = Logger
      .getLogger(PointCheckerModule.class);

  private Pattern pZip;
  private Pattern pSeg;

  /********* MUST HAVE *********/
  private Boolean multi = false;
  private String zipRegExp;
  private String segRegExp;
  private String correctDir;
  private String incorrectDir;
  private String nameFrom;
  private String bossRegExp;
  private Long scanDelay;

  public PointCheckerModule(String configFile) throws JnodeModuleException {
    super(configFile);
    multi = Boolean.valueOf(properties.getProperty(CONFIG_MULTI));
    zipRegExp = properties.getProperty(CONFIG_ZIP);
    segRegExp = properties.getProperty(CONFIG_SEG);
    correctDir = properties.getProperty(CONFIG_CORRECT);
    incorrectDir = properties.getProperty(CONFIG_INCORRECT);
    nameFrom = properties.getProperty(CONFIG_NAME);
    bossRegExp = properties.getProperty(CONFIG_BOSS);
    scanDelay = Long
        .valueOf(properties.getProperty(CONFIG_SCANDELAY, "60"));

    if (multi == null || zipRegExp == null || segRegExp == null
        || correctDir == null || incorrectDir == null
        || nameFrom == null || bossRegExp == null) {
      throw new JnodeModuleException(
          "Invalid configuration: required fields are empty");
    }

    for (String dir : Arrays.asList(correctDir, incorrectDir)) {
      File d = new File(dir);
      if (!(d.canRead() && d.canWrite() && d.isDirectory())) {
        throw new JnodeModuleException(
            "Invalid configuration: directory " + dir
                + " is invalid");
      }
    }
    pZip = Pattern.compile(zipRegExp, Pattern.CASE_INSENSITIVE);
    pSeg = Pattern.compile(segRegExp, Pattern.CASE_INSENSITIVE);
  }

  @Override
  public void handle(IEvent event) {

  }

  @Override
  public void start() {
    synchronized (this) {
      logger.l3("Module started");
      while (true) {
        logger.l4("Scan inbound...");
        for (File file : new File(FtnTools.getInbound()).listFiles()) {
          if (file.isDirectory())
            continue;
          try {
            if (pZip.matcher(file.getName()).matches()) {
              ZipInputStream zis = new ZipInputStream(
                  new FileInputStream(file));
              ZipEntry ze;
              while ((ze = zis.getNextEntry()) != null) {
                if (pSeg.matcher(ze.getName()).matches()) {
                  String name = file.getName() + "#"
                      + ze.getName();
                  readAndCheck(ze.getName(), name, zis,
                      (int) ze.getSize());
                  zis.close();
                  file.delete();
                  break;
                }
              }
            } else if (pSeg.matcher(file.getName()).matches()) {
              FileInputStream fis = new FileInputStream(file);
              readAndCheck(file.getName(), file.getName(), fis,
                  (int) file.length());
              file.delete();
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
        try {
          Thread.sleep(scanDelay * 1000);
        } catch (InterruptedException e) {
        }
      }
    }
  }

  private void readAndCheck(String fileName, String name, InputStream io,
      int size) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    while ((size = io.read(buf, 0, buf.length)) != -1) {
      bos.write(buf, 0, size);
    }
    boolean success = check(name, bos.toByteArray(), multi);
    String newname = ((success) ? correctDir : incorrectDir)
        + File.separator + fileName;
    FileOutputStream fof = new FileOutputStream(newname.toLowerCase());
    fof.write(bos.toByteArray());
    fof.close();
    logger.l3("readAndCheck " + fileName + " " + size + " : " + success);
  }

  private void addError(int linenum, String msg, StringBuffer errors) {
    String error = "Line: " + linenum + " error : " + msg + "\n";
    errors.append(error);
    logger.l3(error);
  }

  private boolean check(String fileName, byte[] data, boolean multi)
      throws IOException {
    StringBuffer errors = new StringBuffer();
    List<FtnNdlAddress> bosses = new ArrayList<>();
    List<Long> points = new ArrayList<>();

    Pattern pBoss = Pattern.compile("^Boss,(" + bossRegExp + ")$");
    Pattern pPoint = Pattern
        .compile("^Point,(\\d+),(\\S+),(\\S+),(\\S+),(\\S+),(\\d+),(\\S*)$");
    String[] lines = new String(data, "CP866").replaceAll("\n", "\r")
        .replaceAll("\r+", "\r").split("\r");
    int linenum = 0;
    int _points = 0;
    boolean bossnotfound = false;
    for (String line : lines) {
      linenum++;
      if (line.startsWith(";")) {
        if (!(multi || bosses.isEmpty())) {
          addError(linenum,
              "No multi pointlist, comment after boss string",
              errors);
        }
        continue;
      }
      Matcher m = pBoss.matcher(line);
      if (m.matches()) {
        FtnNdlAddress boss = NodelistScanner.getInstance().isExists(
            new FtnAddress(m.group(1)));
        if (boss == null) {
          addError(linenum, line + " not found in nodelist", errors);
          bossnotfound = true;
        } else {
          if (multi || bosses.isEmpty()) {
            if (bosses.contains(boss)) {
              addError(linenum, line
                  + " already exists in pointlist", errors);
              bossnotfound = true;
            } else {
              bosses.add(boss);
              points.clear();
              bossnotfound = false;
            }
          } else {
            addError(linenum,
                "Not multi pointlist, next boss found", errors);
          }
          continue;
        }
      }
      m = pPoint.matcher(line);
      if (m.matches()) {
        if (bosses.isEmpty()) {
          addError(linenum,
              "Point string present, but no boss present before",
              errors);
        } else {
          Long point = Long.valueOf(m.group(1));
          if (points.contains(point)) {
            if (bossnotfound) {
              addError(
                  linenum,
                  "Point for boss, thats not found in nodelist",
                  errors);
            } else {
              addError(linenum,
                  "Point " + point + " already exists for "
                      + bosses.get(bosses.size() - 1),
                  errors);
            }
          } else {
            String flags = m.group(7);
            if (flags != null && checkflags(flags, linenum, errors)) {
              points.add(point);
              _points++;
            }
          }
        }
        continue;
      }
      addError(linenum, "Unknown line: " + line, errors);
    }
    boolean isReg = false;
    boolean isNet = false;
    if (multi && bosses.size() > 1) {
      // TODO
    }
    // create netmail :-)
    boolean success = (errors.length() == 0);
    String subject = (success) ? "Segment checked : OK"
        : "Segment checked: Errors";
    String text = "File: " + fileName + "\nDate: " + new Date().toString()
        + "\n" + "Lines: " + linenum + "\n" + "Flags: "
        + ((isReg) ? "regional" : (isNet) ? "net" : "local") + "\n"
        + "Boss lines: " + bosses.size() + "\n" + "Point lines: "
        + _points + "\n";
    if (!success)
      text += errors.toString();
    for (FtnNdlAddress boss : bosses) {
      FtnTools.writeNetmail(FtnTools.getPrimaryFtnAddress(),
          boss.clone(), nameFrom,
          boss.getLine().split(",")[4].replace('_', ' '), subject,
          text);
    }
    return success;
  }

  private boolean checkflags(String flagline, int linenum, StringBuffer errors) {
    if (flagline.length() == 0)
      return true;
    String regex = "^(CM|MO|LO|V21|V22|V29|V32|V32B|V32T|V33|V34|HST|"
        + "H14|H16|H96|MAX|PEP|CSP|ZYX|VFC|Z19|V90C|V90S|X2C|X2S|MNP|V42|"
        + "MN|V42B|XA|XB|XC|XP|XR|XW|XX|V110L|V110H|V120L|V120H|X75|ISDN|"
        + "IBN|IFC|ITN|IVM|IFT|ITX|IUC|IMI|ISE|IP|IEM|#\\d{2}|T[a-zA-Z]{2}|"
        + "I(EM|NA|MI|MA|TN|FT):([-a-zA-Z0-9\\.@]+))$";
    boolean uflag = false;
    boolean status = true;
    Pattern p = Pattern.compile(regex);

    for (String flag : flagline.split(",")) {
      if (p.matcher(flag).matches()) {
        continue;
      }
      if (flag.equals("U")) {
        uflag = true;
        continue;
      }
      if (uflag) {
        continue;
      }
      addError(linenum, "unknown flag: " + flag, errors);
      status = false;

    }
    return status;

  }

}
TOP

Related Classes of org.jnode.pointchecker.PointCheckerModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.