Package org.cipango.kaleo.xcap.dao

Source Code of org.cipango.kaleo.xcap.dao.FileXcapDao$XpathXmlResource

// ========================================================================
// Copyright 2009 NEXCOM Systems
// ------------------------------------------------------------------------
// Licensed 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.cipango.kaleo.xcap.dao;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;

import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.xerces.parsers.DOMParser;
import org.cipango.kaleo.xcap.XcapException;
import org.cipango.kaleo.xcap.XcapResource;
import org.cipango.kaleo.xcap.XcapResourceProcessor;
import org.cipango.kaleo.xcap.XcapService;
import org.cipango.kaleo.xcap.XcapUri;
import org.cipango.kaleo.xcap.XcapResourceImpl.NodeType;
import org.jaxen.JaxenException;
import org.jaxen.dom.DOMXPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class FileXcapDao implements XcapDao
{
  private Logger _log = LoggerFactory.getLogger(FileXcapDao.class);
 
  private File _baseDir;
  private boolean _createUser = true;
  private static TransformerFactory _transformerfactory = TransformerFactory.newInstance();
 
  public void init(Collection<XcapResourceProcessor> processors) throws Exception
  {
    if (_baseDir == null)
      throw new IllegalAccessException("Base dirctory is not set");
    _baseDir.mkdirs();
    if (!_baseDir.isDirectory())
      throw new IllegalAccessException("Base directory " + _baseDir + " is not a directory");
    if (!_baseDir.canWrite())
      throw new IllegalAccessException("Base directory " + _baseDir + " is not writable");
    for (XcapResourceProcessor processor : processors)
    {
      File file = new File(_baseDir, processor.getAuid());
      file.mkdir();
      new File(file, XcapUri.GLOBAL).mkdir();
      new File(file, XcapUri.USERS).mkdir();
    }

    _log.debug("File XCAP DAO is started with base directory: {}", _baseDir);
  }
 
  public void delete(XcapResource resource) throws XcapException
  {
    if (!resource.isAllDocument())
    {
      Node node = resource.getSelectedResource().getDom();
      if (node instanceof Attr)
      {
        Attr attr = (Attr) node;
        attr.getOwnerElement().removeAttribute(node.getLocalName());
      }
      else
      {
        node.getParentNode().removeChild(node);
      }
    }
  }

  public XmlResource getDocument(XcapUri uri, boolean create)
      throws XcapException
  {
    File file = getFile(uri);
    if (!file.exists())
    {
      if (!uri.isGlobal() && _createUser && !file.getParentFile().exists()
          && file.getParentFile().getName().equals(getEscapePath(uri.getUser())))
        file.getParentFile().mkdir();
      return null;
    }
    if (file.isDirectory())
    {
      _log.debug("Find resource with document selector {}, but is a directory", uri.getDocumentSelector());
      return null;
    }
    return new FileXmlResource(file);
  }

  public XmlResource getNode(XcapResource resource) throws XcapException
  {
    return getNode(resource, resource.getXcapUri().getNodeSelector());
  }

  public XmlResource getNode(XcapResource resource, String nodeSelector) throws XcapException
  {
    try
    {
      DOMXPath xPath = new DOMXPath(nodeSelector);
      for (String prefix : resource.getNamespaceContext().keySet())
        xPath.addNamespace(prefix, resource.getNamespaceContext().get(prefix));
      Node node = (Node) xPath.selectSingleNode(resource.getDocument().getDom());
      if (node == null)
        return null;
      return new XpathXmlResource(node);
    }
    catch (JaxenException e)
    {
      throw XcapException.newInternalError(e);
    }
  }
 
  public void save(XcapResource resource) throws XcapException, IOException
  {
    if (XcapService.DELETE.equals(resource.getAction())
        && resource.isAllDocument())
    {
      FileXmlResource res = (FileXmlResource) resource.getDocument();
      res.getFile().delete();
      resource.setDocument(null);
      return;
    }
     
    File file = ((FileXmlResource) resource.getDocument()).getFile();
    try
    {
      FileOutputStream os = new FileOutputStream(file);
      os.write(getContent(resource.getDocument().getDom(), false));
      os.close();
    }
    catch (Exception e)
    {
      throw new XcapException("Unable to save document in " + file,
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
    }
  }

  public void update(XcapResource resource, String content)
      throws XcapException
  {
    if ( resource.getDocument() != null)
      ((FileXmlResource) resource.getDocument()).setModified(true);
   
    if (resource.getNodeType() != null && resource.getNodeType() == NodeType.ATTRIBUTE)
    {
      if (resource.isCreation())
      {
        XmlResource parent = getNode(resource, resource.getParentPath());
        Element element = (Element) parent.getDom();
        element.setAttribute(resource.getNodeName(), content);
      }
      else
      {
        Attr attr = (Attr) resource.getSelectedResource().getDom();
        attr.setValue(content);
      }
    }
    else
    {
      Document document = null;
      try {     
        DOMParser parser = new DOMParser();
        parser.parse(new InputSource(new ByteArrayInputStream(content.getBytes())));
        document = parser.getDocument();     
      } catch (Throwable e) {
        XcapException e1 = new XcapException("Unable to read XML content",
            HttpServletResponse.SC_CONFLICT, e);
        StringBuffer sb = new StringBuffer();
        sb.append(XcapException.XCAP_ERROR_HEADER);
        sb.append("<not-well-formed/>");
        sb.append(XcapException.XCAP_ERROR_FOOTER);
       
        e1.setContent(XcapException.XCAP_ERROR_CONTENT_TYPE, sb.toString().getBytes());
 
        throw e1;
      }
      if (resource.isAllDocument())
      {
        resource.setDocument(new FileXmlResource(
            getFile(resource.getXcapUri()),
            document));
      }
      else
      {
        if (resource.isCreation())
        {
          XmlResource parent = getNode(resource, resource.getParentPath());
          Node newNode = parent.getDom().getOwnerDocument().importNode(document.getDocumentElement(), true)
          parent.getDom().appendChild(newNode);
        }
        else
        {
          Node previous = resource.getSelectedResource().getDom();
          Node newNode = previous.getOwnerDocument().importNode(document.getDocumentElement(), true)
          previous.getParentNode().replaceChild(newNode, previous);
          ((XpathXmlResource) resource.getSelectedResource()).setNode(newNode);
        }
      }
    }
  }
 
  private File getFile(XcapUri uri)
  {
    return new File(_baseDir, getEscapePath(uri.getDocumentSelector()));
  }
 
  private String getEscapePath(String path)
  {
    return path.replace(":", "%3A").replace("@", "%40");
  }
 
  public File getBaseDir()
  {
    return _baseDir;
  }

  public void setBaseDir(File baseDir)
  {
    _baseDir = baseDir;
  }
 
  private static byte[] getContent(Node node, boolean omitXmlDeclaration)
  {
    try
    {
      DOMSource domSource = new DOMSource(node);
      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
     
      Transformer transformer = _transformerfactory.newTransformer();
      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omitXmlDeclaration ? "yes" : "no");
      transformer.transform(domSource, new StreamResult(byteOut));

      return byteOut.toByteArray();
    }
    catch (TransformerException e)
    {
      throw XcapException.newInternalError(e);
    }
  }
 
  public String getFirstExistAncestor(XcapUri uri)
  {
    File file = getFile(uri);
    while (!file.exists() && !file.equals(_baseDir))
      file = file.getParentFile();
    if (file.equals(_baseDir))
      return "";
    return file.getAbsolutePath().substring(_baseDir.getAbsolutePath().length() + 1).replace('\\', '/');
  }

  public static class XpathXmlResource implements XmlResource
  {
    private Node _node;
   
    public XpathXmlResource(Node node)
    {
      _node = node;
    }
   
    public byte[] getBytes()
    {
      return FileXcapDao.getContent(_node, true);
    }

    public Node getDom()
    {
      return _node;
    }
   
    public void setNode(Node node)
    {
      _node = node;
    }
   
  }
 
  public static class FileXmlResource implements XmlResource
  {
    private File _file;
    private Document _document;
    public boolean _modified = false;
   
    public FileXmlResource(File file)
    {
      _file = file;
    }
   
    public FileXmlResource(File file, Document document)
    {
      _file = file;
      _document = document;
      _modified = true;
    }
   
    public byte[] getBytes()
    {
      if (_modified)
      {
        return FileXcapDao.getContent(_document, false);
      }
      else
      {
        try
        {
          FileInputStream is = new FileInputStream(_file);
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          byte[] b = new byte[512];
          int read;
          while ((read = is.read(b)) != -1)
            os.write(b, 0, read);
          b = os.toByteArray();
          os.close();
          is.close();
          return b;
         
        }
        catch (IOException e)
        {
          throw XcapException.newInternalError(e);
        }
      }
    }

    public Node getDom()
    {
      if (_document == null)
      {
        try
        {
          DOMParser parser = new DOMParser();
          parser.parse(new InputSource(new FileInputStream(_file)));
          _document = parser.getDocument();
        }
        catch (Exception e)
        {
          throw XcapException.newInternalError(e);
        }
      }
      return _document;
    }
   
    protected File getFile()
    {
      return _file;
    }
   
    protected void setModified(boolean modified)
    {
      _modified = modified;
    }
  }




}
TOP

Related Classes of org.cipango.kaleo.xcap.dao.FileXcapDao$XpathXmlResource

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.