Package com.bradmcevoy.http.webdav

Source Code of com.bradmcevoy.http.webdav.PropertySourcePatchSetter

package com.bradmcevoy.http.webdav;

import com.bradmcevoy.http.Resource;
import com.bradmcevoy.http.Response;
import com.bradmcevoy.http.Response.Status;
import com.bradmcevoy.http.exceptions.NotAuthorizedException;
import com.bradmcevoy.http.values.ValueAndType;
import com.bradmcevoy.http.values.ValueWriters;
import com.bradmcevoy.http.webdav.PropFindResponse.NameAndError;
import com.bradmcevoy.http.webdav.PropPatchRequestParser.ParseResult;
import com.bradmcevoy.property.PropertySource;
import com.bradmcevoy.property.PropertySource.PropertyMetaData;
import com.bradmcevoy.property.PropertySource.PropertySetException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author brad
*/
public class PropertySourcePatchSetter implements PropPatchSetter {

  private static final Logger log = LoggerFactory.getLogger(PropertySourcePatchSetter.class);
  private final List<PropertySource> propertySources;
  private final ValueWriters valueWriters;

  public PropertySourcePatchSetter(List<PropertySource> propertySources, ValueWriters valueWriters) {
    this.propertySources = propertySources;
    this.valueWriters = valueWriters;
  }

  public PropertySourcePatchSetter(List<PropertySource> propertySources) {
    this.propertySources = propertySources;
    this.valueWriters = new ValueWriters();
  }

  /**
   * This returns true for all resources, but it actually depends on the
   * configured property sources.
   *
   * If no property sources support a given resource, a proppatch attempt
   * will return 404's for all properties
   *
   * @param r
   * @return
   */
  public boolean supports(Resource r) {
    return true;
  }

  public PropFindResponse setProperties(String href, ParseResult parseResult, Resource r) {
    log.trace("setProperties");
    Map<QName, ValueAndType> knownProps = new HashMap<QName, ValueAndType>();

    Map<Status, List<NameAndError>> errorProps = new EnumMap<Status, List<NameAndError>>(Status.class);
    for (Entry<QName, String> entry : parseResult.getFieldsToSet().entrySet()) {
      QName name = entry.getKey();
      boolean found = false;
      for (PropertySource source : propertySources) {
        PropertyMetaData meta = source.getPropertyMetaData(entry.getKey(), r);
        if (meta != null && !meta.isUnknown()) {
          found = true;
          if (meta.isWritable()) {
            Object val = parse(name, entry.getValue(), meta.getValueType());
            try {
              log.trace("setProperties: setProperty: name: {} source: []", name, source);
              source.setProperty(name, val, r);
              knownProps.put(name, new ValueAndType(null, meta.getValueType()));
              break;
            } catch (NotAuthorizedException e) {
              log.trace("setProperties: NotAuthorised to write property: {}", name, e);
              addErrorProp(errorProps, Response.Status.SC_UNAUTHORIZED, name, "Not authorised");
              break;
            } catch (PropertySetException ex) {
              log.trace("setProperties: PropertySetException when writing property {}", name, ex);
              addErrorProp(errorProps, ex.getStatus(), name, ex.getErrorNotes());
              break;
            }
          } else {
            log.debug("property is not writable in source: " + source.getClass());
            addErrorProp(errorProps, Response.Status.SC_FORBIDDEN, name, "Property is read only");
            break;
          }
        } else {
          //log.debug( "not found in: " + source.getClass().getCanonicalName() );
        }
      }
      if (!found) {
        log.debug("property not found: " + entry.getKey());
        addErrorProp(errorProps, Status.SC_NOT_FOUND, entry.getKey(), "Unknown property");
      }
    }
    if (parseResult.getFieldsToRemove() != null) {
      for (QName name : parseResult.getFieldsToRemove()) {
        boolean found = false;
        for (PropertySource source : propertySources) {
          PropertyMetaData meta = source.getPropertyMetaData(name, r);
          if (meta != null && !meta.isUnknown()) {
            found = true;
            if (meta.isWritable()) {
              try {
                log.trace("clearProperty");
                source.clearProperty(name, r);
                knownProps.put(name, new ValueAndType(null, meta.getValueType()));
                break;
              } catch (NotAuthorizedException e) {
                addErrorProp(errorProps, Response.Status.SC_UNAUTHORIZED, name, "Not authorised");
                break;
              } catch (PropertySetException ex) {
                addErrorProp(errorProps, ex.getStatus(), name, ex.getErrorNotes());
                break;
              }
            } else {
              log.debug("property is not writable in source: " + source.getClass());
              addErrorProp(errorProps, Response.Status.SC_FORBIDDEN, name, "Property is read only");
              break;
            }
          } else {
            //log.debug( "not found in: " + source.getClass().getCanonicalName() );
          }
        }
        if (!found) {
          log.debug("property not found to remove: " + name);
          addErrorProp(errorProps, Status.SC_NOT_FOUND, name, "Unknown property");
        }
      }
    }
    if (log.isDebugEnabled()) {
      if (errorProps.size() > 0) {
        log.debug("errorProps: " + errorProps.size() + " listing property sources:");
        for (PropertySource s : propertySources) {
          log.debug("  source: " + s.getClass().getCanonicalName());
        }
      }
    }
    PropFindResponse resp = new PropFindResponse(href, knownProps, errorProps);
    return resp;
  }

  private void addErrorProp(Map<Status, List<NameAndError>> errorProps, Status stat, QName name, String err) {
    List<NameAndError> list = errorProps.get(stat);
    if (list == null) {
      list = new ArrayList<NameAndError>();
      errorProps.put(stat, list);
    }
    NameAndError ne = new NameAndError(name, err);
    list.add(ne);

  }

  private Object parse(QName key, String value, Class valueType) {
    return valueWriters.parse(key, valueType, value);
  }
}
TOP

Related Classes of com.bradmcevoy.http.webdav.PropertySourcePatchSetter

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.