/** Returns the path to be used as the servlet name. */
  private Path getPagePath(String pathName) {
    Path rootDir = _webApp.getRootDirectory();
    String realPath = _webApp.getRealPath(pathName);
    Path path = rootDir.lookupNative(realPath);

    if (path.isFile() && path.canRead()) return path;

    java.net.URL url;
    ClassLoader loader = _webApp.getClassLoader();
    if (loader != null) {
      url = _webApp.getClassLoader().getResource(pathName);

      String name = url != null ? url.toString() : null;

      path = null;
      if (url != null && (name.endsWith(".jar") || name.endsWith(".zip")))
        path = JarPath.create(Vfs.lookup(url.toString())).lookup(pathName);
      else if (url != null) path = Vfs.lookup(url.toString());

      if (path != null && path.isFile() && path.canRead()) return path;
    }

    url = ClassLoader.getSystemResource(pathName);
    String name = url != null ? url.toString() : null;

    path = null;
    if (url != null && (name.endsWith(".jar") || name.endsWith(".zip")))
      path = JarPath.create(Vfs.lookup(url.toString())).lookup(pathName);
    else if (url != null) path = Vfs.lookup(url.toString());

    if (path != null && path.isFile() && path.canRead()) return path;
    else return null;
  }
  private Class generateProxy() {
    try {
      JavaClassLoader jLoader = new JavaClassLoader(_cl.getClassLoader());

      JavaClass jClass = new JavaClass(jLoader);
      jClass.setAccessFlags(Modifier.PUBLIC);
      ConstantPool cp = jClass.getConstantPool();

      jClass.setWrite(true);

      jClass.setMajor(49);
      jClass.setMinor(0);

      String superClassName = _cl.getName().replace('.', '/');
      String thisClassName = superClassName + "$BeanProxy";

      jClass.setSuperClass(superClassName);
      jClass.setThisClass(thisClassName);

      jClass.addInterface("java/io/Serializable");
      jClass.addInterface("com/caucho/config/inject/HandleAware");

      generateConstructors(jClass, superClassName);

      generateWriteReplace(jClass);
      generateSetHandle(jClass);

      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      WriteStream out = Vfs.openWrite(bos);

      jClass.write(out);

      out.close();

      byte[] buffer = bos.toByteArray();

      if (false) {
        String userName = System.getProperty("user.name");

        out = Vfs.lookup("file:/tmp/" + userName + "/qa/temp.class").openWrite();
        out.write(buffer, 0, buffer.length);
        out.close();
      }

      String cleanName = thisClassName.replace('/', '.');
      _proxyClass = (Class<X>) new ProxyClassLoader().loadClass(cleanName, buffer);
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    return _proxyClass;
  }
  public String toString() {
    XmlConfigContext env = XmlConfigContext.getCurrent();

    if (env != null) {
      String file = env.getBaseUri();

      if (file != null) {
        String dir = Vfs.lookup(file).getParent().getURL();

        return Vfs.decode(dir);
      } else return null;
    } else throw new IllegalStateException(L.l("__DIR__ is only available during configuration"));
  }
  private Path writeTempFile(Node node) throws IOException {
    Path workDir = CauchoSystem.getWorkPath().lookup("_xsl");
    workDir.mkdirs();

    // Path temp = workDir.createTempFile("tmp", "xsl");

    WriteStream os = Vfs.lookup("null:").openWrite();
    Crc64Stream crcStream = new Crc64Stream(os.getSource());
    os.init(crcStream);
    try {
      XmlPrinter printer = new XmlPrinter(os);

      printer.printNode(node);
    } finally {
      os.close();
    }

    long crc = crcStream.getCRC();
    CharBuffer cb = new CharBuffer();
    Base64.encode(cb, crc);

    String crcValue = cb.toString().replace('/', '-');

    Path xslPath = workDir.lookup(crcValue + ".xsl");

    // temp.renameTo(xslPath);

    return xslPath;
  }
  public void init() throws ConfigException {
    if (_id == null) throw new ConfigException(L.l("`{0}' is required", "id"));

    if (_location == null) throw new ConfigException(L.l("`{0}' is required", "location"));

    if (_name == null) _name = _location.toString();

    if (_indexString == null) _indexString = "index-all.html";

    _locationPath = Vfs.lookup(_location);

    int split = _indexString.indexOf('#');

    if (split > -1) {
      CharBuffer before = new CharBuffer(_indexString.substring(0, split));
      CharBuffer after = new CharBuffer(_indexString.substring(split + 1));
      CharBuffer index = CharBuffer.allocate();

      boolean isIndex = false;

      for (int i = 1; i <= 27; i++) {
        index.append(before);
        index.append(i);
        index.append(after);

        Path indexPath = _locationPath.lookup(index.toString());

        if (indexPath.exists()) {
          isIndex = true;
          _index.add(indexPath);
        }

        index.clear();
      }

      if (!isIndex) {
        throw new ConfigException(L.l("`{0}' not found", _locationPath.lookup(_indexString)));
      }
    } else _index.add(_locationPath.lookup(_indexString));

    if (_locationPath.getScheme().equals("file")) {
      _isLocal = true;
      Path pwd = Vfs.getPwd();

      if (!_locationPath.getPath().startsWith(pwd.getPath())) _isLocalAbsolute = true;
    }
  }
  /** Tries to open the log. Called from inside _logLock */
  private void openLog() {
    closeLogStream();

    WriteStream os = _os;
    _os = null;

    IoUtil.close(os);

    Path path = getPath();

    if (path == null) {
      path = getPath(CurrentTime.getCurrentTime());
    }

    Path parent = path.getParent();

    try {
      if (!parent.isDirectory()) {
        if (!parent.mkdirs()) {
          /* XXX:
          logWarning(L.l("Can't create log directory {0}.\n",
                         parent));
          */
        }
      }
    } catch (Exception e) {
      logWarning(L.l("Can't create log directory {0}.\n  Exception={1}", parent, e), e);
    }

    Exception exn = null;

    for (int i = 0; i < 3 && _os == null; i++) {
      try {
        _os = path.openAppend();
      } catch (IOException e) {
        exn = e;
      }
    }

    String pathName = path.getPath();

    try {
      if (pathName.endsWith(".gz")) {
        _zipOut = _os;
        _os = Vfs.openWrite(new GZIPOutputStream(_zipOut));
      } else if (pathName.endsWith(".zip")) {
        throw new ConfigException("Can't support .zip in path-format");
      }
    } catch (Exception e) {
      if (exn == null) exn = e;
    }

    if (exn != null)
      logWarning(
          L.l(
              "Can't create log for {0}.\n  User={1} Exception={2}",
              path, System.getProperty("user.name"), exn),
          exn);
  }
Example #7
0
  /** Initialize the servlet with the server's sruns. */
  public void init() throws ServletException {
    _pwd = Vfs.lookup();

    String serverAddress = getInitParameter("server-address");
    if (serverAddress != null) addAddress(serverAddress);

    _loadBalancer = _loadBalanceBuilder.create();
  }
  protected void writeResponse(OutputStream out, Object result) throws IOException, RestException {
    WriteStream ws = Vfs.openWrite(out);

    try {
      XMLStreamWriterImpl writer = new XMLStreamWriterImpl(ws);

      _marshaller.marshal(result, writer);
    } catch (JAXBException e) {
      throw new RuntimeException(e);
    } finally {
      ws.close();
    }
  }
  /** Opens a path based on a Source. */
  ReadStream openPath(Source source) throws TransformerException, IOException {
    String systemId = source.getSystemId();

    Path path;
    if (systemId != null) path = getSearchPath().lookup(systemId);
    else path = getSearchPath().lookup("anonymous.xsl");

    if (source instanceof StreamSource) {
      StreamSource stream = (StreamSource) source;

      InputStream is = stream.getInputStream();

      if (is instanceof ReadStream) {
        ReadStream rs = (ReadStream) is;

        rs.setPath(path);

        return rs;
      } else if (is != null) {
        ReadStream rs = Vfs.openRead(is);
        rs.setPath(path);

        return rs;
      }

      Reader reader = stream.getReader();

      if (reader != null) {
        ReadStream rs = Vfs.openRead(reader);
        rs.setPath(path);

        return rs;
      }
    }

    if (systemId != null) return getSearchPath().lookup(systemId).openRead();

    throw new TransformerException("bad source " + source);
  }
  /** Compile a schema. */
  public Schema compileSchema(String url) throws SAXException, IOException {
    Path path = Vfs.lookup(url);

    ReadStream is = path.openRead();
    try {
      InputSource source = new InputSource(is);
      source.setSystemId(url);

      return compileSchema(source);
    } finally {
      is.close();
    }
  }
  private void initDriverList() {
    try {
      Thread thread = Thread.currentThread();
      ClassLoader loader = thread.getContextClassLoader();

      Enumeration iter = loader.getResources("META-INF/services/java.sql.Driver");
      while (iter.hasMoreElements()) {
        URL url = (URL) iter.nextElement();

        ReadStream is = null;
        try {
          is = Vfs.lookup(url.toString()).openRead();

          String filename;

          while ((filename = is.readLine()) != null) {
            int p = filename.indexOf('#');

            if (p >= 0) filename = filename.substring(0, p);

            filename = filename.trim();
            if (filename.length() == 0) continue;

            try {
              Class cl = Class.forName(filename, false, loader);
              Driver driver = null;

              if (Driver.class.isAssignableFrom(cl)) driver = (Driver) cl.newInstance();

              if (driver != null) {
                log.fine(L.l("DatabaseManager adding driver '{0}'", driver.getClass().getName()));

                _driverList.add(driver);
              }
            } catch (Exception e) {
              log.log(Level.FINE, e.toString(), e);
            }
          }
        } catch (Exception e) {
          log.log(Level.FINE, e.toString(), e);
        } finally {
          if (is != null) is.close();
        }
      }
    } catch (Exception e) {
      log.log(Level.FINE, e.toString(), e);
    }
  }
  /** Parses a stylesheet from the source. */
  protected Node parseStylesheet(Source source) throws TransformerConfigurationException {
    if (source instanceof DOMSource) return ((DOMSource) source).getNode();
    else if (source instanceof StreamSource) {
      InputStream is = ((StreamSource) source).getInputStream();
      ReadStream rs = null;

      try {
        rs = Vfs.openRead(is);
        return parseXSL(rs);
      } catch (Exception e) {
        throw new TransformerConfigurationException(e);
      } finally {
        if (rs != null) rs.close();
      }
    } else return null;
  }
Example #13
0
  public static Path lookupPath(String string, ELContext env, Path pwd) throws ELException {
    if (env == null) env = Config.getEnvironment();

    string = rewritePathString(string);

    Expr expr = new ELParser(env, string).parse();

    Object obj = expr.evalObject(env);

    if (obj == null) throw new NullPointerException(L.l("Path '{0}' evaluated to null.", string));
    if (obj instanceof Path) return (Path) obj;

    String value = Expr.toString(obj, env);

    if (pwd != null) return pwd.lookup(value);
    else return Vfs.lookup(value);
  }
  private void handleExternalBody(String url) throws JspException, ServletException, IOException {
    URL netURL = new URL(url);

    URLConnection conn = netURL.openConnection();

    if (conn instanceof HttpURLConnection) ((HttpURLConnection) conn).setFollowRedirects(true);

    InputStream is = conn.getInputStream();
    try {
      ReadStream in = Vfs.openRead(is);
      String encoding = conn.getContentEncoding();
      String contentType = conn.getContentType();

      if (_charEncoding != null) {
        encoding = _charEncoding;
        if (encoding != null && !encoding.equals("")) in.setEncoding(encoding);
      } else if (encoding != null) in.setEncoding(encoding);
      else if (contentType != null) {
        int p = contentType.indexOf("charset=");
        if (p > 0) {
          CharBuffer cb = new CharBuffer();
          for (int i = p + 8; i < contentType.length(); i++) {
            int ch = contentType.charAt(i);
            if (ch == '"' || ch == '\'') {
            } else if (ch >= 'a' && ch <= 'z') cb.append((char) ch);
            else if (ch >= 'A' && ch <= 'Z') cb.append((char) ch);
            else if (ch >= '0' && ch <= '9') cb.append((char) ch);
            else if (ch == '-' || ch == '_') cb.append((char) ch);
            else break;
          }
          encoding = cb.toString();

          in.setEncoding(encoding);
        }
      }

      JspWriter out = pageContext.getOut();

      int ch;
      while ((ch = in.readChar()) >= 0) out.print((char) ch);
    } finally {
      is.close();
    }
  }
  /** Initialize the JNI. */
  public static void initJNI() {
    if (_isInitJNI.getAndSet(true)) return;

    // order matters because of static init and license checking
    FilesystemPath jniFilePath = JniFilePath.create();

    if (jniFilePath != null) {
      DEFAULT_SCHEME_MAP.put("file", jniFilePath);

      SchemeMap localMap = _localSchemeMap.get();
      if (localMap != null) localMap.put("file", jniFilePath);

      localMap = _localSchemeMap.get(ClassLoader.getSystemClassLoader());
      if (localMap != null) localMap.put("file", jniFilePath);

      Vfs.PWD = jniFilePath;
      Vfs.setPwd(jniFilePath);
    }
  }
  @Override
  public int doCommand(WatchdogArgs args, WatchdogClient client, WebAppDeployClient deployClient) {
    String fileName = args.getDefaultArg();

    if (fileName == null) {
      throw new ConfigException(L.l("Cannot find a filename in command line"));
    }

    CommitBuilder commit = createCommitBuilder(args);

    try {
      WriteStream out = Vfs.openWrite(System.out);

      deployClient.getFile(commit.getId(), fileName, out);

      out.flush();
    } catch (IOException e) {
      throw ConfigException.create(e);
    }

    return 0;
  }
  /**
   * Loads a stylesheet from a named file
   *
   * @param systemId the URL of the file
   */
  public StylesheetImpl newStylesheet(String systemId) throws Exception {
    StylesheetImpl stylesheet = loadPrecompiledStylesheet(systemId, systemId);

    if (stylesheet != null) return stylesheet;

    synchronized (AbstractStylesheetFactory.class) {
      stylesheet = loadPrecompiledStylesheet(systemId, systemId);

      if (stylesheet != null) return stylesheet;

      ReadStream is;

      if (_stylePath != null) is = _stylePath.lookup(systemId).openRead();
      else is = Vfs.lookup(systemId).openRead();

      try {
        return newStylesheet(is);
      } finally {
        if (is != null) is.close();
      }
    }
  }
Example #18
0
  public boolean getFile(String tagName, String fileName, OutputStream os) throws IOException {
    StreamSource fileSource = _deployProxy.getFile(tagName, fileName);

    if (fileSource != null) {
      ReadStream is = null;
      GitObjectStream gitIs = new GitObjectStream(fileSource.getInputStream());

      try {
        is = Vfs.openRead(gitIs);

        is.writeToStream(os);
      } finally {
        gitIs.close();

        IoUtil.close(is);
      }

      return true;
    } else {
      return false;
    }
  }
  public static Source convertToSource(Object xmlObj, String systemId) throws JspException {
    if (xmlObj instanceof String) {
      ReadStream is = Vfs.openString((String) xmlObj);

      return new StreamSource(is, systemId);
    } else if (xmlObj instanceof InputStream) {
      return new StreamSource((InputStream) xmlObj, systemId);
    } else if (xmlObj instanceof Reader) {
      return new StreamSource((Reader) xmlObj, systemId);
    } else if (xmlObj instanceof Node) {
      return new DOMSource((Node) xmlObj, systemId);
    } else if (xmlObj instanceof NodeList) {
      return new DOMSource(((NodeList) xmlObj).item(0), systemId);
    } else if (xmlObj instanceof Source) return (Source) xmlObj;
    else if (xmlObj instanceof ArrayList) {
      ArrayList list = (ArrayList) xmlObj;

      if (list.size() > 0) return convertToSource(list.get(0), systemId);
    }

    throw new JspException(L.l("unknown xml object type '{0}' '{1}'", xmlObj, xmlObj.getClass()));
  }
Example #20
0
  private Map<String, RepositoryTagEntry> readTagMap(AbstractRepository repository, String sha1)
      throws IOException {
    TreeMap<String, RepositoryTagEntry> map = new TreeMap<String, RepositoryTagEntry>();

    InputStream is = repository.openBlob(sha1);
    try {
      ReadStream in = Vfs.openRead(is);

      String tag;

      while ((tag = in.readLine()) != null) {
        String entrySha1 = in.readLine();

        RepositoryTagEntry entry = new RepositoryTagEntry(repository, entrySha1);

        map.put(tag, entry);
      }
    } finally {
      is.close();
    }

    return Collections.unmodifiableMap(map);
  }
 /** Create a ReadStream from a string. utf-8 is used as the encoding */
 public static ReadStream openRead(String path) throws IOException {
   return Vfs.lookup(path).openRead();
 }
 /** Returns the stylesheet search path. */
 public Path getSearchPath() {
   if (_stylePath != null) return _stylePath;
   else return Vfs.getPwd();
 }
Example #23
0
  /** Returns the enhanced .class or null if no enhancement. */
  public byte[] transform(
      ClassLoader loader,
      String className,
      Class<?> oldClass,
      ProtectionDomain domain,
      byte[] buffer) {
    if (isClassMatch(className)) {
      try {
        ClassLoader tempLoader = ((DynamicClassLoader) loader).getNewTempClassLoader();
        DynamicClassLoader workLoader = SimpleLoader.create(tempLoader, getPostWorkPath());
        workLoader.setServletHack(true);
        boolean isModified = true;

        Thread thread = Thread.currentThread();
        ClassLoader oldLoader = thread.getContextClassLoader();

        try {
          Class<?> cl = Class.forName(className.replace('/', '.'), false, workLoader);

          thread.setContextClassLoader(tempLoader);

          Method init = cl.getMethod("_caucho_init", new Class[] {Path.class});
          Method modified = cl.getMethod("_caucho_is_modified", new Class[0]);

          init.invoke(null, Vfs.lookup());

          isModified = (Boolean) modified.invoke(null);
        } catch (Exception e) {
          log.log(Level.FINEST, e.toString(), e);
        } catch (Throwable e) {
          log.log(Level.FINER, e.toString(), e);
        } finally {
          thread.setContextClassLoader(oldLoader);
        }

        if (!isModified) {
          try {
            return load(className);
          } catch (Exception e) {
            log.log(Level.FINER, e.toString(), e);
          }
        }

        ByteCodeParser parser = new ByteCodeParser();
        parser.setClassLoader(_jClassLoader);

        ByteArrayInputStream is;
        is = new ByteArrayInputStream(buffer, 0, buffer.length);

        JavaClass jClass = parser.parse(is);

        return enhance(jClass);
      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new EnhancerRuntimeException(e);
      }
    }

    return null;
  }
  /** Create a new stylesheet from an input stream. */
  public StylesheetImpl newStylesheet(InputStream is) throws Exception {
    ReadStream rs = Vfs.openRead(is);

    return (StylesheetImpl) generate(parseXSL(rs), rs.getPath());
  }
/** Abstract class for a log that rolls over based on size or period. */
public class AbstractRolloverLog implements Closeable {
  private static final L10N L = new L10N(AbstractRolloverLog.class);
  private static final Logger log = Logger.getLogger(AbstractRolloverLog.class.getName());

  // Milliseconds in an hour
  private static final long HOUR = 3600L * 1000L;
  // Milliseconds in a day
  private static final long DAY = 24L * 3600L * 1000L;

  // Default maximum log size = 2G
  private static final long DEFAULT_ROLLOVER_SIZE = Bytes.INFINITE;
  // How often to check size
  private static final long DEFAULT_ROLLOVER_CHECK_PERIOD = 600L * 1000L;

  private static final long ROLLOVER_OVERFLOW_MAX = 64 * 1024 * 1024;

  // prefix for the rollover
  private String _rolloverPrefix;

  // template for the archived files
  private String _archiveFormat;
  // .gz or .zip
  private String _archiveSuffix = "";

  // Cron description of the rollover
  private CronType _rolloverCron;
  // How often the logs are rolled over.
  private long _rolloverPeriod = Period.INFINITE;

  // Maximum size of the log.
  private long _rolloverSize = DEFAULT_ROLLOVER_SIZE;

  // How often the rolloverSize should be checked
  private long _rolloverCheckPeriod = DEFAULT_ROLLOVER_CHECK_PERIOD;

  // How many archives are allowed.
  private int _rolloverCount;

  private Path _pwd = Vfs.lookup();

  private Path _path;

  protected String _pathFormat;

  // private String _format;

  private volatile boolean _isInit;

  // The time of the next period-based rollover
  private long _nextPeriodEnd = -1;
  private final AtomicLong _nextRolloverCheckTime = new AtomicLong();

  // private long _lastTime;

  private final RolloverWorker _rolloverWorker = new RolloverWorker();
  private final FlushWorker _flushWorker = new FlushWorker();
  private final Object _logLock = new Object();

  private volatile boolean _isRollingOver;
  private TempStreamApi _tempStream;
  private long _tempStreamSize;

  private WriteStream _os;
  private WriteStream _zipOut;

  private volatile boolean _isClosed;
  private final RolloverAlarm _rolloverListener;
  private WeakAlarm _rolloverAlarm;

  protected AbstractRolloverLog() {
    _rolloverListener = new RolloverAlarm();
    _rolloverAlarm = new WeakAlarm(_rolloverListener);

    Environment.addCloseListener(this);
  }

  /** Returns the access-log's path. */
  public Path getPath() {
    return _path;
  }

  /** Sets the access-log's path. */
  public void setPath(Path path) {
    _path = path;
  }

  /** Returns the pwd for the rollover log */
  public Path getPwd() {
    return _pwd;
  }

  /** Returns the formatted path */
  public String getPathFormat() {
    return _pathFormat;
  }

  /** Sets the formatted path. */
  public void setPathFormat(String pathFormat) throws ConfigException {
    _pathFormat = pathFormat;

    if (pathFormat.endsWith(".zip")) {
      throw new ConfigException(L.l(".zip extension to path-format is not supported."));
    }
  }

  /** Sets the archive name format */
  public void setArchiveFormat(String format) {
    if (format.endsWith(".gz")) {
      _archiveFormat = format.substring(0, format.length() - ".gz".length());
      _archiveSuffix = ".gz";
    } else if (format.endsWith(".zip")) {
      _archiveFormat = format.substring(0, format.length() - ".zip".length());
      _archiveSuffix = ".zip";
    } else {
      _archiveFormat = format;
      _archiveSuffix = "";
    }
  }

  /** Sets the archive name format */
  public String getArchiveFormat() {
    if (_archiveFormat == null) return _rolloverPrefix + ".%Y%m%d.%H%M";
    else return _archiveFormat;
  }

  /** Sets the log rollover cron specification */
  public void setRolloverCron(CronType cron) {
    _rolloverCron = cron;
  }

  /**
   * Sets the log rollover period, rounded up to the nearest hour.
   *
   * @param period the new rollover period in milliseconds.
   */
  public void setRolloverPeriod(Period period) {
    _rolloverPeriod = period.getPeriod();

    if (_rolloverPeriod > 0) {
      _rolloverPeriod += 3600000L - 1;
      _rolloverPeriod -= _rolloverPeriod % 3600000L;
    } else _rolloverPeriod = Period.INFINITE;
  }

  /**
   * Sets the log rollover period, rounded up to the nearest hour.
   *
   * @return the new period in milliseconds.
   */
  public long getRolloverPeriod() {
    return _rolloverPeriod;
  }

  /**
   * Sets the log rollover size, rounded up to the megabyte.
   *
   * @param bytes maximum size of the log file
   */
  public void setRolloverSize(Bytes bytes) {
    setRolloverSizeBytes(bytes.getBytes());
  }

  public void setRolloverSizeBytes(long size) {
    if (size < 0) _rolloverSize = Bytes.INFINITE;
    else _rolloverSize = size;
  }

  /**
   * Sets the log rollover size, rounded up to the megabyte.
   *
   * @return maximum size of the log file
   */
  public long getRolloverSize() {
    return _rolloverSize;
  }

  /**
   * Sets how often the log rollover will be checked.
   *
   * @param period how often the log rollover will be checked.
   */
  public void setRolloverCheckPeriod(long period) {
    if (period > 1000) _rolloverCheckPeriod = period;
    else if (period > 0) _rolloverCheckPeriod = 1000;

    if (DAY < _rolloverCheckPeriod) {
      log.info(this + " rollover-check-period " + _rolloverCheckPeriod + "ms is longer than 24h");

      _rolloverCheckPeriod = DAY;
    }
  }

  /**
   * Sets how often the log rollover will be checked.
   *
   * @return how often the log rollover will be checked.
   */
  public long getRolloverCheckPeriod() {
    return _rolloverCheckPeriod;
  }

  /** Sets the max rollover files. */
  public void setRolloverCount(int count) {
    _rolloverCount = count;
  }

  public void setLastTime(long lastTime) {
    // _lastTime = lastTime;
  }

  protected boolean isClosed() {
    return _isClosed;
  }

  /** Initialize the log. */
  public void init() throws IOException {
    long now = CurrentTime.getExactTime();

    // server/0263
    // _nextRolloverCheckTime = now + _rolloverCheckPeriod;

    Path path = getPath();

    if (path != null) {
      path.getParent().mkdirs();

      _rolloverPrefix = path.getTail();

      long lastModified = path.getLastModified();

      if (lastModified <= 0 || now < lastModified) {
        lastModified = now;
      }

      // _calendar.setGMTTime(lastModified);

      _nextPeriodEnd = nextRolloverTime(lastModified);
    } else {
      _nextPeriodEnd = nextRolloverTime(now);
    }

    if (_archiveFormat != null || getRolloverPeriod() <= 0) {
    } else if (_rolloverCron != null) _archiveFormat = _rolloverPrefix + ".%Y%m%d.%H";
    else if (getRolloverPeriod() % DAY == 0) _archiveFormat = _rolloverPrefix + ".%Y%m%d";
    else if (getRolloverPeriod() % HOUR == 0) _archiveFormat = _rolloverPrefix + ".%Y%m%d.%H";
    else _archiveFormat = _rolloverPrefix + ".%Y%m%d.%H%M";

    _isInit = true;

    _rolloverListener.requeue(_rolloverAlarm);
    rollover();
  }

  public boolean rollover() {
    long now = CurrentTime.getCurrentTime();

    if (_nextPeriodEnd <= now || _nextRolloverCheckTime.get() <= now) {
      _nextRolloverCheckTime.set(now + _rolloverCheckPeriod);
      _rolloverWorker.wake();

      return true;
    } else return false;
  }

  /** Writes to the underlying log. */
  protected void write(byte[] buffer, int offset, int length) throws IOException {
    /*
    String s = new String(buffer, offset, length);
    if (s.startsWith("127")) {
      System.out.println("WRITE: " + s);
      Thread.dumpStack();

    }
    */

    synchronized (_logLock) {
      if (_isRollingOver && getTempStreamMax() < _tempStreamSize) {
        try {
          _logLock.wait();
        } catch (Exception e) {
        }
      }

      if (!_isRollingOver) {
        if (_os == null) openLog();

        if (_os != null) _os.write(buffer, offset, length);
      } else {
        if (_tempStream == null) {
          _tempStream = createTempStream();
          _tempStreamSize = 0;
        }

        _tempStreamSize += length;
        _tempStream.write(buffer, offset, length, false);
      }
    }
  }

  protected TempStreamApi createTempStream() {
    return new TempStream();
  }

  protected long getTempStreamMax() {
    return ROLLOVER_OVERFLOW_MAX;
  }

  /** Writes to the underlying log. */
  protected void flush() throws IOException {
    _flushWorker.wake();
  }

  protected void flushStream() throws IOException {
    synchronized (_logLock) {
      if (_os != null) _os.flush();

      if (_zipOut != null) _zipOut.flush();
    }
  }

  /** Called from rollover worker */
  private void rolloverLogTask() {
    try {
      if (_isInit) flush();
    } catch (Exception e) {
      log.log(Level.WARNING, e.toString(), e);
    }

    _isRollingOver = true;

    try {
      if (!_isInit) return;

      Path savedPath = null;

      long now = CurrentTime.getCurrentTime();

      long lastPeriodEnd = _nextPeriodEnd;

      _nextPeriodEnd = nextRolloverTime(now);

      Path path = getPath();

      synchronized (_logLock) {
        flushTempStream();

        if (lastPeriodEnd <= now && lastPeriodEnd > 0) {
          closeLogStream();

          savedPath = getSavedPath(lastPeriodEnd - 1);
        } else if (path != null && getRolloverSize() <= path.getLength()) {
          closeLogStream();

          savedPath = getSavedPath(now);
        }
      }

      // archiving of path is outside of the synchronized block to
      // avoid freezing during archive
      if (savedPath != null) {
        movePathToArchive(savedPath);
      }
    } finally {
      synchronized (_logLock) {
        _isRollingOver = false;
        flushTempStream();
      }

      _rolloverListener.requeue(_rolloverAlarm);
    }
  }

  private Path getSavedPath(long time) {
    if (getPathFormat() == null) return getArchivePath(time);
    else return null;
  }

  /** Tries to open the log. Called from inside _logLock */
  private void openLog() {
    closeLogStream();

    WriteStream os = _os;
    _os = null;

    IoUtil.close(os);

    Path path = getPath();

    if (path == null) {
      path = getPath(CurrentTime.getCurrentTime());
    }

    Path parent = path.getParent();

    try {
      if (!parent.isDirectory()) {
        if (!parent.mkdirs()) {
          /* XXX:
          logWarning(L.l("Can't create log directory {0}.\n",
                         parent));
          */
        }
      }
    } catch (Exception e) {
      logWarning(L.l("Can't create log directory {0}.\n  Exception={1}", parent, e), e);
    }

    Exception exn = null;

    for (int i = 0; i < 3 && _os == null; i++) {
      try {
        _os = path.openAppend();
      } catch (IOException e) {
        exn = e;
      }
    }

    String pathName = path.getPath();

    try {
      if (pathName.endsWith(".gz")) {
        _zipOut = _os;
        _os = Vfs.openWrite(new GZIPOutputStream(_zipOut));
      } else if (pathName.endsWith(".zip")) {
        throw new ConfigException("Can't support .zip in path-format");
      }
    } catch (Exception e) {
      if (exn == null) exn = e;
    }

    if (exn != null)
      logWarning(
          L.l(
              "Can't create log for {0}.\n  User={1} Exception={2}",
              path, System.getProperty("user.name"), exn),
          exn);
  }

  private void movePathToArchive(Path savedPath) {
    if (savedPath == null) return;

    synchronized (_logLock) {
      closeLogStream();
    }

    Path path = getPath();

    String savedName = savedPath.getTail();

    try {
      if (!savedPath.getParent().isDirectory()) savedPath.getParent().mkdirs();
    } catch (Exception e) {
      logWarning(L.l("Can't open archive directory {0}", savedPath.getParent()), e);
    }

    try {
      if (path.exists()) {
        WriteStream os = null;
        OutputStream out = null;

        // *.gz and *.zip are copied.  Others are just renamed
        if (savedName.endsWith(".gz")) {
          os = savedPath.openWrite();
          out = new GZIPOutputStream(os);
        } else if (savedName.endsWith(".zip")) {
          os = savedPath.openWrite();

          ZipOutputStream zip = new ZipOutputStream(os);
          String entryName = savedName.substring(0, savedName.length() - 4);
          ZipEntry entry = new ZipEntry(entryName);
          zip.putNextEntry(entry);

          out = zip;
        }

        if (out != null) {
          try {
            path.writeToStream(out);
          } finally {
            try {
              out.close();
            } catch (Exception e) {
              // can't log in log rotation routines
            }

            try {
              if (out != os) os.close();
            } catch (Exception e) {
              // can't log in log rotation routines
            }
          }
        } else {
          path.renameTo(savedPath);
        }
      }
    } catch (Exception e) {
      logWarning(L.l("Error rotating logs: {0}", e.toString()), e);
    }

    try {
      path.remove();
      /*
      try {
        if (! path.truncate())
          path.remove();
      } catch (IOException e) {
        path.remove();

        throw e;
      }
      */
    } catch (Exception e) {
      logWarning(L.l("Error truncating logs"), e);
    }

    if (_rolloverCount > 0) removeOldLogs();
  }

  /** Removes logs passing the rollover count. */
  private void removeOldLogs() {
    try {
      Path path = getPath();
      Path parent = path.getParent();

      String[] list = parent.list();

      ArrayList<String> matchList = new ArrayList<String>();

      Pattern archiveRegexp = getArchiveRegexp();
      for (int i = 0; i < list.length; i++) {
        Matcher matcher = archiveRegexp.matcher(list[i]);

        if (matcher.matches()) matchList.add(list[i]);
      }

      Collections.sort(matchList);

      if (_rolloverCount <= 0 || matchList.size() < _rolloverCount) return;

      for (int i = 0; i + _rolloverCount < matchList.size(); i++) {
        try {
          parent.lookup(matchList.get(i)).remove();
        } catch (Throwable e) {
        }
      }
    } catch (Throwable e) {
    }
  }

  private Pattern getArchiveRegexp() {
    StringBuilder sb = new StringBuilder();

    String archiveFormat = getArchiveFormat();

    for (int i = 0; i < archiveFormat.length(); i++) {
      char ch = archiveFormat.charAt(i);

      switch (ch) {
        case '.':
        case '\\':
        case '*':
        case '?':
        case '+':
        case '(':
        case ')':
        case '{':
        case '}':
        case '|':
          sb.append("\\");
          sb.append(ch);
          break;
        case '%':
          sb.append(".+");
          i++;
          break;
        default:
          sb.append(ch);
          break;
      }
    }

    return Pattern.compile(sb.toString());
  }

  /**
   * Returns the path of the format file
   *
   * @param time the archive date
   */
  protected Path getPath(long time) {
    String formatString = getPathFormat();

    if (formatString == null)
      throw new IllegalStateException(L.l("getPath requires a format path"));

    String pathString = getFormatName(formatString, time);

    return getPwd().lookup(pathString);
  }

  /**
   * Returns the name of the archived file
   *
   * @param time the archive date
   */
  protected Path getArchivePath(long time) {
    Path path = getPath();

    String archiveFormat = getArchiveFormat();

    String name = getFormatName(archiveFormat + _archiveSuffix, time);
    Path newPath = path.getParent().lookup(name);

    if (newPath.exists()) {
      if (archiveFormat.indexOf("%H") < 0) archiveFormat = archiveFormat + ".%H%M";
      else if (archiveFormat.indexOf("%M") < 0) archiveFormat = archiveFormat + ".%M";

      for (int i = 0; i < 100; i++) {
        String suffix;

        if (i == 0) suffix = _archiveSuffix;
        else suffix = "." + i + _archiveSuffix;

        name = getFormatName(archiveFormat + suffix, time);

        newPath = path.getParent().lookup(name);

        if (!newPath.exists()) break;
      }
    }

    return newPath;
  }

  /**
   * Returns the name of the archived file
   *
   * @param time the archive date
   */
  protected String getFormatName(String format, long time) {
    if (time <= 0) time = CurrentTime.getCurrentTime();

    if (format != null) return QDate.formatLocal(time, format);
    else if (_rolloverCron != null)
      return _rolloverPrefix + "." + QDate.formatLocal(time, "%Y%m%d.%H");
    else if (getRolloverPeriod() % (24 * 3600 * 1000L) == 0)
      return _rolloverPrefix + "." + QDate.formatLocal(time, "%Y%m%d");
    else return _rolloverPrefix + "." + QDate.formatLocal(time, "%Y%m%d.%H");
  }

  /** error messages from the log itself */
  private void logWarning(String msg, Throwable e) {
    EnvironmentStream.logStderr(msg, e);
  }

  private long nextRolloverTime(long time) {
    if (_rolloverCron != null) return _rolloverCron.nextTime(time);
    else return Period.periodEnd(time, getRolloverPeriod());
  }

  /** Closes the log, flushing the results. */
  public void close() throws IOException {
    _isClosed = true;

    _rolloverWorker.wake();

    _rolloverWorker.close();

    synchronized (_logLock) {
      closeLogStream();
    }

    Alarm alarm = _rolloverAlarm;
    _rolloverAlarm = null;

    if (alarm != null) alarm.dequeue();
  }

  /** Tries to close the log. */
  private void closeLogStream() {
    try {
      WriteStream os = _os;
      _os = null;

      if (os != null) os.close();
    } catch (Throwable e) {
      // can't log in log routines
    }

    try {
      WriteStream zipOut = _zipOut;
      _zipOut = null;

      if (zipOut != null) zipOut.close();
    } catch (Throwable e) {
      // can't log in log routines
    }
  }

  /** Called from inside _logLock */
  private void flushTempStream() {
    TempStreamApi ts = _tempStream;
    _tempStream = null;
    _tempStreamSize = 0;

    try {
      if (ts != null) {
        if (_os == null) openLog();

        try {
          ReadStream is = ts.openRead();

          try {
            is.writeToStream(_os);
          } finally {
            is.close();
          }
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          ts.destroy();
        }
      }
    } finally {
      _logLock.notifyAll();
    }
  }

  @Override
  public String toString() {
    Path path = _path;

    if (path != null) return getClass().getSimpleName() + "[" + path.getTail() + "]";
    else return getClass().getSimpleName() + "[" + path + "]";
  }

  class RolloverWorker extends AbstractTaskWorker {
    @Override
    public long runTask() {
      rolloverLogTask();

      return -1;
    }
  }

  class FlushWorker extends AbstractTaskWorker {
    @Override
    public long runTask() {
      try {
        flushStream();
      } catch (IOException e) {
        log.log(Level.FINER, e.toString(), e);
      }

      return -1;
    }
  }

  class RolloverAlarm implements AlarmListener {
    @Override
    public void handleAlarm(Alarm alarm) {
      if (isClosed()) return;

      try {
        _rolloverWorker.wake();
      } finally {
        alarm.queue(_rolloverCheckPeriod);
      }
    }

    void requeue(Alarm alarm) {
      if (isClosed() || alarm == null) return;

      long now = CurrentTime.getCurrentTime();

      long nextCheckTime;

      if (getRolloverSize() <= 0 || _rolloverCheckPeriod <= 0) nextCheckTime = now + DAY;
      else nextCheckTime = now + _rolloverCheckPeriod;

      if (_nextPeriodEnd <= nextCheckTime) {
        alarm.queueAt(_nextPeriodEnd);
      } else {
        alarm.queueAt(nextCheckTime);
      }
    }
  }
}
Example #26
0
  /** Sets the root directory. */
  public void setRootDirectory(Path path) {
    _rootDir = path;

    Vfs.setPwd(path, getClassLoader());
  }
Example #27
0
 public static Path lookupPath(String string) throws ELException {
   return lookupPath(string, Config.getEnvironment(), Vfs.lookup());
 }
Example #28
0
 public static Path lookupPath(String string, ELContext env) throws ELException {
   return lookupPath(string, env, Vfs.lookup());
 }