Java tutorial
/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.rest.providers; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.rest.util.UserRequestParams; import org.dspace.rest.util.UtilHelper; import org.sakaiproject.entitybus.EntityReference; import org.sakaiproject.entitybus.EntityView; import org.sakaiproject.entitybus.entityprovider.EntityProvider; import org.sakaiproject.entitybus.entityprovider.EntityProviderManager; import org.sakaiproject.entitybus.entityprovider.capabilities.*; import org.sakaiproject.entitybus.entityprovider.extension.Formats; import org.sakaiproject.entitybus.entityprovider.extension.RequestGetter; import org.sakaiproject.entitybus.entityprovider.extension.RequestStorage; import org.sakaiproject.entitybus.exception.EntityException; import org.sakaiproject.entitybus.rest.EntityEncodingManager; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @SuppressWarnings("unchecked") public abstract class AbstractBaseProvider implements EntityProvider, Resolvable, CollectionResolvable, InputTranslatable, RequestAware, Outputable, ActionsExecutable, Redirectable, RequestStorable, RequestInterceptor { protected RequestStorage reqStor; protected boolean withdrawn; protected String user = ""; protected String pass = ""; protected String userc = ""; protected String passc = ""; protected String query, _order, _sort, loggedUser, _sdate, _edate; protected int _start, _limit; protected List<Integer> sortOptions = new ArrayList<Integer>(); protected Collection _collection = null; protected Community _community = null; private static Logger log = Logger.getLogger(AbstractBaseProvider.class); protected Map<String, String> func2actionMapGET = new HashMap<String, String>(); protected Map<String, String> func2actionMapPUT = new HashMap<String, String>(); protected Map<String, String> func2actionMapPOST = new HashMap<String, String>(); protected Map<String, String> func2actionMapDELETE = new HashMap<String, String>(); protected Map<String, Class<?>[]> funcParamsGET = new HashMap<String, Class<?>[]>(); protected Map<String, Class<?>[]> funcParamsPUT = new HashMap<String, Class<?>[]>(); protected Map<String, Class<?>[]> funcParamsPOST = new HashMap<String, Class<?>[]>(); protected Map<String, Class<?>[]> funcParamsDELETE = new HashMap<String, Class<?>[]>(); protected Map<String, String[]> inputParamsPOST = new HashMap<String, String[]>(); protected Map<String, String> func2actionMapGET_rev = new HashMap<String, String>(); protected Map<String, String> func2actionMapPUT_rev = new HashMap<String, String>(); protected Map<String, String> func2actionMapPOST_rev = new HashMap<String, String>(); protected Map<String, String> func2actionMapDELETE_rev = new HashMap<String, String>(); protected Class<?> processedEntity = null; protected Constructor<?> entityConstructor = null; protected RequestGetter requestGetter; protected EntityProviderManager entityProviderManager; protected String format = ""; protected String[] fields; protected String status; protected String submitter, reviewer; protected boolean collections = false; protected boolean trim = false; protected boolean parents = false; protected boolean children = false; protected boolean groups = false; protected boolean replies = false; protected String[] type; // protected String action; public AbstractBaseProvider(EntityProviderManager entityProviderManager) { this.entityProviderManager = entityProviderManager; entityProviderManager.registerEntityProvider(this); } protected void initMappings(Class<?> processedEntity) { // scan for methods; Method[] entityMethods = processedEntity.getMethods(); for (Method m : entityMethods) { //System.out.println("checked method " + m.getName()); String fieldPUT = func2actionMapPUT.get(m.getName()); if (fieldPUT != null) { // System.out.println("added " + fieldPUT + ":" + m.getName()); addParameters(fieldPUT, m.getParameterTypes(), funcParamsPUT); addMethod(fieldPUT, m.getName(), func2actionMapPUT_rev); } String fieldGET = func2actionMapGET.get(m.getName()); if (fieldGET != null) { addParameters(fieldGET, m.getParameterTypes(), funcParamsGET); addMethod(fieldGET, m.getName(), func2actionMapGET_rev); } String fieldPOST = func2actionMapPOST.get(m.getName()); if (fieldPOST != null) { addParameters(fieldPOST, m.getParameterTypes(), funcParamsPOST); addMethod(fieldPOST, m.getName(), func2actionMapPOST_rev); } String fieldDELETE = func2actionMapDELETE.get(m.getName()); if (fieldDELETE != null) { addParameters(fieldDELETE, m.getParameterTypes(), funcParamsDELETE); addMethod(fieldDELETE, m.getName(), func2actionMapDELETE_rev); } } } public void setRequestStorage(RequestStorage rStor) { this.reqStor = rStor; } public void destroy() { entityProviderManager.unregisterEntityProvider(this); } public String userInfo() { String ipaddr = ""; try { ipaddr = this.entityProviderManager.getRequestGetter().getRequest().getRemoteAddr(); } catch (NullPointerException ex) { } return "user:" + loggedUser + ":ip_addr=" + ipaddr + ":"; } public String readIStoString(InputStream is) throws IOException { if (is != null) { StringBuilder sb = new StringBuilder(); String line; try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } } finally { is.close(); } return sb.toString(); } else { return ""; } } public void before(EntityView view, HttpServletRequest req, HttpServletResponse res) { log.info(userInfo() + "starting to write for collection adding"); try { if (req.getContentType().equals("application/json")) { view.setExtension("json"); format = "json"; } else if (req.getContentType().equals("application/xml")) { view.setExtension("xml"); format = "xml"; } else if (req.getContentType().startsWith("multipart/form-data")) { view.setExtension("stream"); format = "stream"; } else { view.setExtension("json"); format = "json"; } } catch (Exception ex) { if (view.getFormat().equals("xml")) { view.setExtension("xml"); format = "xml"; } else { view.setExtension("json"); format = "json"; } } try { if (!(req.getHeader("user").isEmpty() && req.getHeader("pass").isEmpty())) { userc = req.getHeader("user"); passc = req.getHeader("pass"); } } catch (NullPointerException nu) { userc = ""; passc = ""; } } public void after(EntityView view, HttpServletRequest req, HttpServletResponse res) { } public UserRequestParams refreshParams(Context context) { UserRequestParams uparam = new UserRequestParams(); try { user = reqStor.getStoredValue("user").toString(); } catch (NullPointerException ex) { user = ""; } try { pass = reqStor.getStoredValue("pass").toString(); } catch (NullPointerException ex) { pass = ""; } try { if (!(userc.isEmpty() && passc.isEmpty())) { user = userc; pass = passc; } } catch (Exception ex) { ex.printStackTrace(); } // now try to login user loggedUser = "anonymous"; try { EPerson eUser = EPerson.findByEmail(context, user); if ((eUser.canLogIn()) && (eUser.checkPassword(pass))) { context.setCurrentUser(eUser); loggedUser = eUser.getName(); } else { throw new EntityException("Bad username or password", user, 403); } } catch (SQLException sql) { // System.out.println(sql.toString()); sql.printStackTrace(); } catch (AuthorizeException auth) { throw new EntityException("Unauthorised", user, 401); } catch (NullPointerException ne) { if (!(user.equals("") && pass.equals(""))) { throw new EntityException("Bad username or password", user, 403); } } this.collections = "true".equals(reqStor.getStoredValue("collections")); uparam.setCollections(this.collections); this.trim = "true".equals(reqStor.getStoredValue("trim")); uparam.setTrim(this.trim); this.parents = "true".equals(reqStor.getStoredValue("parents")); uparam.setParents(this.parents); this.children = "true".equals(reqStor.getStoredValue("children")); uparam.setChildren(this.children); this.groups = "true".equals(reqStor.getStoredValue("groups")); uparam.setGroups(this.groups); this.replies = "true".equals(reqStor.getStoredValue("replies")); uparam.setReplies(this.replies); // try { // action = reqStor.getStoredValue("action").toString(); // uparam.setAction(action); // } catch (NullPointerException ex) { // action = ""; // } try { query = reqStor.getStoredValue("query").toString(); uparam.setQuery(query); } catch (NullPointerException ex) { query = ""; } try { Object o = reqStor.getStoredValue("fields"); if (o instanceof String) { fields = new String[] { o.toString() }; } else if (o instanceof String[]) { fields = (String[]) o; } else if (o == null) { fields = null; } uparam.setFields(fields); } catch (NullPointerException ex) { fields = null; } try { status = reqStor.getStoredValue("status").toString(); uparam.setStatus(status); } catch (NullPointerException ex) { status = ""; } try { submitter = reqStor.getStoredValue("submitter").toString(); uparam.setSubmitter(submitter); } catch (NullPointerException ex) { submitter = ""; } try { reviewer = reqStor.getStoredValue("reviewer").toString(); uparam.setReviewer(reviewer); } catch (NullPointerException ex) { reviewer = ""; } try { String bundleStr = reqStor.getStoredValue("type").toString(); uparam.setType(bundleStr.split(",")); } catch (NullPointerException ex) { type = null; } try { _order = reqStor.getStoredValue("order").toString(); uparam.setOrder(_order); } catch (NullPointerException ex) { _order = ""; } try { _sort = reqStor.getStoredValue("sort").toString(); uparam.setSort(_sort); } catch (NullPointerException ex) { _sort = ""; } // both parameters are used according to requirements if (_order.length() > 0 && _sort.equals("")) { _sort = _order; } try { _start = Integer.parseInt(reqStor.getStoredValue("start").toString()); uparam.setStart(_start); } catch (NullPointerException ex) { _start = 0; } try { _limit = Integer.parseInt(reqStor.getStoredValue("limit").toString()); uparam.setLimit(_limit); } catch (NullPointerException ex) { _limit = 0; } // some checking for invalid values if (_limit < 0) { _limit = 0; } try { _sdate = reqStor.getStoredValue("startdate").toString(); } catch (NullPointerException ex) { _sdate = null; } try { _edate = reqStor.getStoredValue("enddate").toString(); } catch (NullPointerException ex) { _edate = null; } try { withdrawn = reqStor.getStoredValue("withdrawn").toString().equalsIgnoreCase("true"); } catch (NullPointerException ex) { withdrawn = false; } // defining sort fields and values _sort = _sort.toLowerCase(); String[] sort_arr = _sort.split(","); for (String option : sort_arr) { if (option.startsWith("submitter")) { sortOptions.add(UtilHelper.SORT_SUBMITTER); } else if (option.startsWith("email")) { sortOptions.add(UtilHelper.SORT_EMAIL); } else if (option.startsWith("firstname")) { sortOptions.add(UtilHelper.SORT_FIRSTNAME); } else if (option.startsWith("lastname")) { sortOptions.add(UtilHelper.SORT_LASTNAME); } else if (option.startsWith("fullname")) { sortOptions.add(UtilHelper.SORT_FULL_NAME); } else if (option.startsWith("language")) { sortOptions.add(UtilHelper.SORT_LANGUAGE); } else if (option.startsWith("lastmodified")) { sortOptions.add(UtilHelper.SORT_LASTMODIFIED); } else if (option.startsWith("countitems")) { sortOptions.add(UtilHelper.SORT_COUNT_ITEMS); } else if (option.startsWith("name")) { sortOptions.add(UtilHelper.SORT_NAME); } else { sortOptions.add(UtilHelper.SORT_ID); } if ((option.endsWith("_desc") || option.endsWith("_reverse"))) { int i = sortOptions.get(sortOptions.size() - 1); sortOptions.remove(sortOptions.size() - 1); i += 100; sortOptions.add(i); } } int intcommunity = 0; int intcollection = 0; // integer values used in some parts try { intcommunity = Integer.parseInt(reqStor.getStoredValue("community").toString()); } catch (NullPointerException nul) { } try { _community = Community.find(context, intcommunity); } catch (SQLException sql) { } try { intcollection = Integer.parseInt(reqStor.getStoredValue("collection").toString()); } catch (NullPointerException nul) { } try { _collection = Collection.find(context, intcollection); } catch (SQLException sql) { } if ((intcommunity > 0) && (intcollection > 0)) { throw new EntityException("Bad request", "Community and collection selected", 400); } if ((intcommunity > 0) && (_community == null)) { throw new EntityException("Bad request", "Unknown community", 400); } if ((intcollection > 0) && (_collection == null)) { throw new EntityException("Bad request", "Unknown collection", 400); } return uparam; } public String[] getHandledInputFormats() { return new String[] { Formats.HTML, Formats.XML, Formats.JSON, "stream" }; } public Object translateFormattedData(EntityReference ref, String format, InputStream input, Map<String, Object> params) { String IS = ""; if (format.equals("xml") || format.equals("json")) { try { IS = readIStoString(input); // System.out.println("is+= " + IS); } catch (IOException ex) { ex.printStackTrace(); } } Map<String, Object> decodedInput = null; EntityEncodingManager em = new EntityEncodingManager(null, null); if (format.equals("xml")) { decodedInput = em.decodeData(IS, Formats.XML); } else if (format.equals("json")) { decodedInput = em.decodeData(IS, Formats.JSON); } else if (format.equals("stream")) { try { ServletFileUpload upload = new ServletFileUpload(); FileItemIterator iter = upload.getItemIterator(requestGetter.getRequest()); while (iter.hasNext()) { FileItemStream item = iter.next(); return item.openStream(); } } catch (Exception e) { e.printStackTrace(); } } System.out.println("== translate formated data called"); System.out.println("got: \n" + IS + "\ndecoded " + decodedInput); return decodedInput; } public void removeConn(Context context) { // close connection to prevent connection problems try { if (context != null) { context.complete(); } } catch (Exception ex) { ex.printStackTrace(); } } public void setRequestGetter(RequestGetter requestGetter) { this.requestGetter = requestGetter; } public String[] getHandledOutputFormats() { return new String[] { Formats.JSON, Formats.XML, Formats.FORM, Formats.ATOM }; } public void addParameters(String function, Class<?>[] parameters, Map<String, Class<?>[]> mappings_parameters) { mappings_parameters.put(function, parameters); } public void addMethod(String field, String function, Map<String, String> mappings_rev) { mappings_rev.put(field, function); } public String getMethod(String field, Map<String, String> mappings_rev) { return mappings_rev.get(field); } public String[] getSegments() { return getSegments(null); } public String[] getSegments(Map<String, Object> params) { String segments[] = {}; if (params != null) { if (params.containsKey("pathInfo")) { segments = params.get("pathInfo").toString().split("/"); } } else { if (reqStor.getStoredValue("pathInfo") != null) { segments = reqStor.getStoredValue("pathInfo").toString().split("/"); } } return segments; } public Object getEntity(EntityReference ref) { String segments[] = getSegments(); if (segments[segments.length - 1].startsWith("count")) { return getEntity(ref, segments[segments.length - 2] + "count"); } return getEntity(ref, segments[3]); } public Object getEntity(EntityReference ref, String action) { if (action.lastIndexOf(".") > 0) { action = action.substring(0, action.lastIndexOf(".")); } if (func2actionMapGET_rev.containsKey(action)) { Object result; String function = getMethod(action, func2actionMapGET_rev); if (function == null) { throw new EntityException("Bad request", "Method not supported - not defined", 400); } Context context = null; try { context = new Context(); UserRequestParams uparams = refreshParams(context); Object CE = entityConstructor.newInstance(); Method method = CE.getClass().getMethod(function, funcParamsGET.get(action)); result = method.invoke(CE, ref, uparams, context); } catch (NoSuchMethodException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Not found", "Method not supported ", 404); } catch (SQLException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "SQL error", 500); } catch (InvocationTargetException ex) { if (ex.getCause() != null) { log.error(ex.getCause(), ex.getCause()); throw new EntityException(ex.getCause().toString(), "Invocation Target Exception", 500); } else { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } } catch (Exception ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } finally { removeConn(context); } return result; } else { throw new EntityException("Bad request", "Method not supported " + action, 400); } } public void deleteEntity(EntityReference ref, Map<String, Object> params) { String segments[] = getSegments(params); String action = ""; Map<String, Object> inputVar = new HashMap<String, Object>(); for (int x = 0; x < segments.length; x++) { switch (x) { case 1: inputVar.put("base", segments[x]); break; case 2: inputVar.put("id", segments[x]); break; case 3: inputVar.put("element", segments[x]); break; case 4: String s = segments[x]; if (s != null && !"".equals(s)) { if (s.lastIndexOf(".") > 0) { s = s.substring(0, s.lastIndexOf(".")); } } inputVar.put("eid", s); break; case 5: inputVar.put("trail", segments[x]); break; default: break; } } if (segments.length > 3) { action = segments[3]; } if (func2actionMapDELETE_rev.containsKey(action)) { String function = getMethod(action, func2actionMapDELETE_rev); if (function == null) { throw new EntityException("Bad request", "Method not supported - not defined", 400); } Context context = null; try { context = new Context(); refreshParams(context); Object CE = entityConstructor.newInstance(); Method method = CE.getClass().getMethod(function, funcParamsDELETE.get(action)); method.invoke(CE, ref, inputVar, context); } catch (NoSuchMethodException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Not found", "Meethod not supported " + segments[3], 404); } catch (SQLException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "SQL error", 500); } catch (InvocationTargetException ex) { if (ex.getCause() != null) { log.error(ex.getCause(), ex.getCause()); throw new EntityException(ex.getCause().toString(), "Invocation Target Exception", 500); } else { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } } catch (Exception ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } finally { removeConn(context); } } else { throw new EntityException("Bad request", "Method not supported " + action, 400); } } public void updateEntity(EntityReference ref, Object entity, Map<String, Object> params) { Map<String, Object> inputVar = (HashMap<String, Object>) entity; String segments[] = getSegments(params); String action = ""; if (segments.length > 3) { action = segments[3]; if (action.lastIndexOf(".") > 0) { action = action.substring(0, action.lastIndexOf(".")); } } if (func2actionMapPUT_rev.containsKey(action)) { String function = getMethod(action, func2actionMapPUT_rev); if (function == null) { throw new EntityException("Bad request", "Method not supported - not defined", 400); } Context context = null; try { context = new Context(); refreshParams(context); Object CE = entityConstructor.newInstance(); Method method = CE.getClass().getMethod(function, funcParamsPUT.get(action)); method.invoke(CE, ref, inputVar, context); } catch (NoSuchMethodException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Not found", "Meethod not supported " + segments[3], 404); } catch (SQLException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "SQL error", 500); } catch (InvocationTargetException ex) { if (ex.getCause() != null) { log.error(ex.getCause(), ex.getCause()); throw new EntityException(ex.getCause().toString(), "Invocation Target Exception", 500); } else { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } } catch (Exception ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } finally { removeConn(context); } } else { throw new EntityException("Bad request", "Maethod not supported " + action, 400); } } public String createEntity(EntityReference ref, Object entity, Map<String, Object> params) { String result; Map<String, Object> inputVar = new HashMap<String, Object>(); if (entity instanceof Map) { inputVar = (HashMap<String, Object>) entity; } String function; String[] mandatory_params; String action = ""; String segments[] = getSegments(params); if (segments.length > 2) { action = segments[segments.length - 1]; if (action.lastIndexOf(".") > 0) { action = action.substring(0, action.lastIndexOf(".")); } } if (func2actionMapPOST_rev.containsKey(action)) { function = func2actionMapPOST_rev.get(action); if (function == null) { throw new EntityException("Bad request", "Method not supported - not defined", 400); } mandatory_params = inputParamsPOST.get(function); if (mandatory_params != null) { for (String param : mandatory_params) { if (inputVar.get(param) == null) { throw new EntityException("Bad request", "Incomplete request [mandatory param]", 400); } } } Context context = null; try { context = new Context(); refreshParams(context); Object CE = entityConstructor.newInstance(); Method method = CE.getClass().getMethod(function, funcParamsPOST.get(action)); if (entity instanceof Map) { result = (String) method.invoke(CE, ref, inputVar, context); } else { result = (String) method.invoke(CE, ref, entity, context); } } catch (NoSuchMethodException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Not found", "Method not supported ", 404); } catch (SQLException ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "SQL error", 500); } catch (InvocationTargetException ex) { if (ex.getCause() != null) { log.error(ex.getCause(), ex.getCause()); throw new EntityException(ex.getCause().toString(), "Invocation Target Exception", 500); } else { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } } catch (Exception ex) { log.error(ex.getMessage(), ex); throw new EntityException("Internal server error", "Unknown error", 500); } finally { removeConn(context); } return result; } else { throw new EntityException("Bad request", "Method not supported " + action, 400); } } }