示例#1
0
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException {
    try {
      // Get the path
      String path = request.getPathInfo();

      if (path == null) {
        response.sendError(
            HttpServletResponse.SC_BAD_REQUEST, "URL has no extra path information specified.");
        return;
      }

      int firstSlash = path.indexOf('/', 1);
      if (firstSlash < 0 && path.length() == 1) {
        response.sendError(400, "Module not specified.");
        return;
      }
      String moduleName = firstSlash < 0 ? path.substring(1) : path.substring(1, firstSlash);
      path = firstSlash < 0 ? "" : path.substring(firstSlash);

      AtomModule module = (AtomModule) modules.get(moduleName);
      if (module == null) {
        response.sendError(400, "Module " + moduleName + " not found.");
        return;
      }

      User user = null;
      if (noAuth.get(moduleName) == null) {
        // Authenticate
        user = authenticate(request, response);
        if (user == null) {
          // You now get a challenge if there is no user
          return;
        }
      }

      final Principal principal = new UserXmldbPrincipal(WebDAV.BASIC_AUTH, user);
      HttpServletRequest wrappedRequest =
          new HttpServletRequestWrapper(request) {
            public Principal getUserPrincipal() {
              return principal;
            }
          };

      // Handle the resource
      DBBroker broker = null;
      try {
        broker = pool.get(user);
        module.process(
            broker,
            new HttpRequestMessage(request, path, '/' + moduleName),
            new HttpResponseMessage(response));
      } catch (NotFoundException ex) {
        LOG.info("Resource " + path + " not found by " + moduleName, ex);
        response.sendError(404, ex.getMessage());
      } catch (PermissionDeniedException ex) {
        LOG.info(
            "Permission denied to " + path + " by " + moduleName + " for " + user.getName(), ex);
        response.sendError(401, ex.getMessage());
      } catch (BadRequestException ex) {
        LOG.info("Bad request throw from module " + moduleName, ex);
        response.sendError(400, ex.getMessage());
      } catch (EXistException ex) {
        LOG.fatal("Exception getting broker from pool for user " + user.getName(), ex);
        response.sendError(500, "Service is not available.");
      } finally {
        pool.release(broker);
      }
    } catch (IOException ex) {
      LOG.fatal("I/O exception on request.", ex);
      try {
        response.sendError(500, "Service is not available.");
      } catch (IOException finalEx) {
        LOG.fatal("Cannot return 500 on exception.", ex);
      }
    }
  }
示例#2
0
  /* (non-Javadoc)
   * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
   */
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    // Configure BrokerPool
    try {
      if (BrokerPool.isConfigured()) {
        LOG.debug("Database already started. Skipping configuration ...");
      } else {
        // The database isn't started, so we'll start it
        String confFile = config.getInitParameter("configuration");
        String dbHome = config.getInitParameter("basedir");
        String start = config.getInitParameter("start");

        if (confFile == null) {
          confFile = "conf.xml";
        }
        dbHome =
            (dbHome == null)
                ? config.getServletContext().getRealPath(".")
                : config.getServletContext().getRealPath(dbHome);

        LOG.debug("AtomServlet: exist.home=" + dbHome);

        File f = new File(dbHome + File.separator + confFile);
        LOG.debug("reading configuration from " + f.getAbsolutePath());

        if (!f.canRead()) {
          throw new ServletException(
              "configuration file " + confFile + " not found or not readable");
        }
        Configuration configuration = new Configuration(confFile, dbHome);
        if (start != null && start.equals("true")) {
          startup(configuration);
        }
      }
      pool = BrokerPool.getInstance();

      // The default user is used when there is no authentication
      String option = config.getInitParameter("use-default-user");
      boolean useDefaultUser = true;
      if (option != null) {
        useDefaultUser = option.trim().equals("true");
      }
      if (useDefaultUser) {
        option = config.getInitParameter("user");
        if (option != null) {
          defaultUsername = option;
        }
        option = config.getInitParameter("password");
        if (option != null) {
          defaultPassword = option;
        }
        defaultUser = getDefaultUser();
        if (defaultUser != null) {
          LOG.info("Using default user " + defaultUsername + " for all unauthorized requests.");
        } else {
          LOG.error(
              "Default user "
                  + defaultUsername
                  + " cannot be found.  A BASIC AUTH challenge will be the default.");
        }
      } else {
        LOG.info(
            "No default user.  All requires must be authorized or will result in a BASIC AUTH challenge.");
        defaultUser = null;
      }

      // Currently, we only support basic authentication
      authenticator = new BasicAuthenticator(pool);
    } catch (EXistException e) {
      throw new ServletException("No database instance available");
    } catch (DatabaseConfigurationException e) {
      throw new ServletException("Unable to configure database instance: " + e.getMessage(), e);
    }

    // get form and container encoding's
    formEncoding = config.getInitParameter("form-encoding");
    if (formEncoding == null) {
      formEncoding = DEFAULT_ENCODING;
    }
    String containerEncoding = config.getInitParameter("container-encoding");
    if (containerEncoding == null) {
      containerEncoding = DEFAULT_ENCODING;
    }

    // Load all the modules
    // modules = new HashMap<String,AtomModule>();
    modules = new HashMap();
    noAuth = new HashMap();

    String configFileOpt = config.getInitParameter("config-file");
    File dbHome = pool.getConfiguration().getExistHome();
    File atomConf;
    if (configFileOpt == null) atomConf = new File(dbHome, "atom-services.xml");
    else atomConf = new File(config.getServletContext().getRealPath(configFileOpt));
    config
        .getServletContext()
        .log("Checking for atom configuration in " + atomConf.getAbsolutePath());
    if (atomConf.exists()) {
      config.getServletContext().log("Loading configuration " + atomConf.getAbsolutePath());
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
      docFactory.setNamespaceAware(true);
      DocumentBuilder docBuilder = null;
      Document confDoc = null;
      InputStream is = null;
      try {
        is = new FileInputStream(atomConf);
        InputSource src = new InputSource(new InputStreamReader(is, formEncoding));
        URI docBaseURI = atomConf.toURI();
        src.setSystemId(docBaseURI.toString());
        docBuilder = docFactory.newDocumentBuilder();
        confDoc = docBuilder.parse(src);

        confDoc.getDocumentElement();

        // Add all the modules
        NodeList moduleConfList = confDoc.getElementsByTagNameNS(CONF_NS, "module");
        for (int i = 0; i < moduleConfList.getLength(); i++) {
          Element moduleConf = (Element) moduleConfList.item(i);
          String name = moduleConf.getAttribute("name");
          if (modules.get(name) != null) {
            throw new ServletException(
                "Module '" + name + "' is configured more than once ( child # " + (i + 1));
          }
          if ("false".equals(moduleConf.getAttribute("authenticate"))) {
            noAuth.put(name, Boolean.TRUE);
          }
          String className = moduleConf.getAttribute("class");
          if (className != null && className.length() > 0) {
            try {
              Class moduleClass = Class.forName(className);
              AtomModule amodule = (AtomModule) moduleClass.newInstance();
              modules.put(name, amodule);
              amodule.init(new ModuleContext(config, name, atomConf.getParent()));
            } catch (Exception ex) {
              throw new ServletException(
                  "Cannot instantiate class "
                      + className
                      + " for module '"
                      + name
                      + "' due to exception: "
                      + ex.getMessage(),
                  ex);
            }
          } else {
            // no class means query
            Query query = new Query();
            modules.put(name, query);

            String allowQueryPost = moduleConf.getAttribute("query-by-post");
            if ("true".equals(allowQueryPost)) {
              query.setQueryByPost(true);
            }

            NodeList methodList = moduleConf.getElementsByTagNameNS(CONF_NS, "method");
            for (int m = 0; m < methodList.getLength(); m++) {
              Element methodConf = (Element) methodList.item(m);
              String type = methodConf.getAttribute("type");
              if (type == null) {
                LOG.warn("No type specified for method in module " + name);
                continue;
              }
              // What I want but can't have because of JDK 1.4
              // URI baseURI = URI.create(methodConf.getBaseURI());
              URI baseURI = docBaseURI;
              String queryRef = methodConf.getAttribute("query");
              if (queryRef == null) {
                LOG.warn("No query specified for method " + type + " in module " + name);
                continue;
              }
              boolean fromClasspath = "true".equals(methodConf.getAttribute("from-classpath"));
              Query.MethodConfiguration mconf = query.getMethodConfiguration(type);
              if (mconf == null) {
                LOG.warn("Unknown method " + type + " in module " + name);
                continue;
              }
              String responseContentType = methodConf.getAttribute("content-type");
              if (responseContentType != null && responseContentType.trim().length() != 0) {
                mconf.setContentType(responseContentType);
              }

              URL queryURI = null;
              if (fromClasspath) {
                LOG.debug(
                    "Nope. Attempting to get resource "
                        + queryRef
                        + " from "
                        + Atom.class.getName());
                queryURI = Atom.class.getResource(queryRef);
              } else {
                queryURI = baseURI.resolve(queryRef).toURL();
              }
              LOG.debug(
                  "Loading from module "
                      + name
                      + " method "
                      + type
                      + " from resource "
                      + queryURI
                      + " via classpath("
                      + fromClasspath
                      + ") and ref ("
                      + queryRef
                      + ")");
              if (queryURI == null) {
                throw new ServletException(
                    "Cannot find resource " + queryRef + " for module " + name);
              }
              mconf.setQuerySource(queryURI);
            }
            query.init(new ModuleContext(config, name, atomConf.getParent()));
          }
        }

      } catch (IOException e) {
        LOG.warn(e);
        throw new ServletException(e.getMessage());
      } catch (SAXException e) {
        LOG.warn(e);
        throw new ServletException(e.getMessage());
      } catch (ParserConfigurationException e) {
        LOG.warn(e);
        throw new ServletException(e.getMessage());
      } catch (EXistException e) {
        LOG.warn(e);
        throw new ServletException(e.getMessage());
      } finally {
        if (is != null) {
          try {
            is.close();
          } catch (IOException ex) {
          }
        }
      }
    } else {
      try {
        AtomProtocol protocol = new AtomProtocol();
        modules.put("edit", protocol);
        protocol.init(new ModuleContext(config, "edit", dbHome.getAbsolutePath()));
        AtomFeeds feeds = new AtomFeeds();
        modules.put("content", feeds);
        feeds.init(new ModuleContext(config, "content", dbHome.getAbsolutePath()));
        Query query = new Query();
        query.setQueryByPost(true);
        modules.put("query", query);
        query.init(new ModuleContext(config, "query", dbHome.getAbsolutePath()));
        Query topics = new Query();
        modules.put("topic", topics);
        topics
            .getMethodConfiguration("GET")
            .setQuerySource(topics.getClass().getResource("topic.xq"));
        topics.init(new ModuleContext(config, "topic", dbHome.getAbsolutePath()));
        Query introspect = new Query();
        modules.put("introspect", introspect);
        introspect
            .getMethodConfiguration("GET")
            .setQuerySource(introspect.getClass().getResource("introspect.xq"));
        introspect.init(new ModuleContext(config, "introspect", dbHome.getAbsolutePath()));
      } catch (EXistException ex) {
        throw new ServletException("Exception during module init(): " + ex.getMessage(), ex);
      }
    }

    // XML lib checks....
    StringBuffer xmlLibMessage = new StringBuffer();
    if (XmlLibraryChecker.hasValidParser(xmlLibMessage)) {
      LOG.info(xmlLibMessage);
    } else {
      LOG.warn(xmlLibMessage);
    }
    xmlLibMessage.delete(0, xmlLibMessage.length());
    if (XmlLibraryChecker.hasValidTransformer(xmlLibMessage)) {
      LOG.info(xmlLibMessage);
    } else {
      LOG.warn(xmlLibMessage);
    }
  }