public void test02SearchSingleNodeByDate() { try { PropertyMap props = new PropertyMap(); PropertyKey key = TestOne.aDate; Date date = new Date(); String type = TestOne.class.getSimpleName(); props.put(key, date); AbstractNode node = createTestNode(type, props); boolean includeDeletedAndHidden = true; boolean publicOnly = false; List<SearchAttribute> searchAttributes = new LinkedList<SearchAttribute>(); searchAttributes.add(new TextualSearchAttribute(AbstractNode.type, type, SearchOperator.AND)); searchAttributes.add(new FilterSearchAttribute(key, date, SearchOperator.AND)); Result result = searchNodeCommand.execute(includeDeletedAndHidden, publicOnly, searchAttributes); assertEquals(1, result.size()); assertTrue(result.get(0).equals(node)); } catch (FrameworkException ex) { logger.log(Level.SEVERE, ex.toString()); fail("Unexpected exception"); } }
private List<Linkable> findPossibleEntryPointsByName( final SecurityContext securityContext, HttpServletRequest request, final String name) throws FrameworkException { List<Linkable> possibleEntryPoints = (List<Linkable>) request.getAttribute(POSSIBLE_ENTRY_POINTS); if (CollectionUtils.isNotEmpty(possibleEntryPoints)) { return possibleEntryPoints; } if (name.length() > 0) { logger.log(Level.FINE, "Requested name: {0}", name); final Query query = StructrApp.getInstance(securityContext).nodeQuery(); query.and(AbstractNode.name, name); query.and().orType(Page.class).orTypes(File.class); // Searching for pages needs super user context anyway Result results = query.getResult(); logger.log(Level.FINE, "{0} results", results.size()); request.setAttribute(POSSIBLE_ENTRY_POINTS, results.getResults()); return (List<Linkable>) results.getResults(); } return Collections.EMPTY_LIST; }
/** * Find the page with the lowest position value which is visible in the current securit context * * @param securityContext * @return * @throws FrameworkException */ private Page findIndexPage(final SecurityContext securityContext) throws FrameworkException { Result<Page> results = StructrApp.getInstance(securityContext) .nodeQuery(Page.class) .sort(Page.position) .order(false) .getResult(); Collections.sort( results.getResults(), new GraphObjectComparator(Page.position, GraphObjectComparator.ASCENDING)); // Find first visible page Page page = null; if (!results.isEmpty()) { int i = 0; while (page == null || (i < results.size() && !securityContext.isVisible(page))) { page = results.get(i++); } } return page; }
public void test04SearchByLocation() { try { final PropertyMap props = new PropertyMap(); final PropertyKey lat = TestSeven.latitude; final PropertyKey lon = TestSeven.longitude; final String type = TestSeven.class.getSimpleName(); props.put(lat, 50.12284d); props.put(lon, 8.73923d); props.put(AbstractNode.name, "TestSeven-0"); AbstractNode node = createTestNode(type, props); boolean includeDeletedAndHidden = true; boolean publicOnly = false; List<SearchAttribute> searchAttributes = new LinkedList<SearchAttribute>(); searchAttributes.add(new TextualSearchAttribute(AbstractNode.type, type, SearchOperator.AND)); searchAttributes.add( new DistanceSearchAttribute( "Hanauer Landstr. 200, 60314 Frankfurt, Germany", 10.0, SearchOperator.AND)); Result result = searchNodeCommand.execute(includeDeletedAndHidden, publicOnly, searchAttributes); assertEquals(1, result.size()); assertTrue(result.get(0).equals(node)); } catch (FrameworkException ex) { logger.log(Level.SEVERE, ex.toString()); fail("Unexpected exception"); } }
public void testSimpleSearchOnNode() { try { final PropertyMap properties = new PropertyMap(); final PropertyKey<String> key = TestFour.stringProperty; properties.put(key, "test"); final TestFour testEntity = createTestNode(TestFour.class, properties); assertNotNull(testEntity); try (final Tx tx = app.tx()) { // check value from database assertEquals("test", testEntity.getProperty(key)); Result<TestFour> result = app.nodeQuery(TestFour.class).and(key, "test").getResult(); assertEquals(result.size(), 1); assertEquals(result.get(0), testEntity); } } catch (FrameworkException fex) { fail("Unable to store array"); } }
public void test01SearchSingleNodeByName() { try { PropertyMap props = new PropertyMap(); PropertyKey key = AbstractNode.name; String name = "89w3hklsdfghsdkljth"; props.put(key, name); AbstractNode node = createTestNode(TestOne.class.getSimpleName(), props); boolean includeDeletedAndHidden = true; boolean publicOnly = false; List<SearchAttribute> searchAttributes = new LinkedList<SearchAttribute>(); searchAttributes.add(new TextualSearchAttribute(key, name, SearchOperator.AND)); Result result = searchNodeCommand.execute(includeDeletedAndHidden, publicOnly, searchAttributes); assertTrue(result.size() == 1); assertTrue(result.get(0).equals(node)); // Change name attribute and search again name = "klppptzoehigösoiutzüw0e9hg"; node.setProperty(key, name); searchAttributes.clear(); searchAttributes.add(new TextualSearchAttribute(key, name, SearchOperator.AND)); result = searchNodeCommand.execute(includeDeletedAndHidden, publicOnly, searchAttributes); assertTrue(result.size() == 1); assertTrue(result.get(0).equals(node)); } catch (FrameworkException ex) { logger.log(Level.SEVERE, ex.toString()); fail("Unexpected exception"); } }
@Override public Result doGet( PropertyKey sortKey, boolean sortDescending, int pageSize, int page, String offsetId) throws FrameworkException { if (wrappedResource != null) { Result result = wrappedResource.doGet(sortKey, sortDescending, pageSize, page, offsetId); try { Collections.sort(result.getResults(), new GraphObjectComparator(sortKey, sortOrder)); } catch (Throwable t) { throw new FrameworkException("base", new InvalidSortKey(sortKey)); } return result; } throw new IllegalPathException(); }
public void testSimpleSearchOnRelationship() { try { final TestOne testOne = createTestNode(TestOne.class); final TestFour testFour = createTestNode(TestFour.class); final Property<String> key = OneFourOneToOne.stringProperty; assertNotNull(testOne); assertNotNull(testFour); final OneFourOneToOne testEntity = createTestRelationship(testOne, testFour, OneFourOneToOne.class); assertNotNull(testEntity); try (final Tx tx = app.tx()) { testEntity.setProperty(key, "test"); tx.success(); } try (final Tx tx = app.tx()) { // check value from database assertEquals("test", testEntity.getProperty(key)); Result<OneFourOneToOne> result = app.relationshipQuery(OneFourOneToOne.class).and(key, "test").getResult(); assertEquals(result.size(), 1); assertEquals(result.get(0), testEntity); } } catch (FrameworkException fex) { fail("Unable to store array"); } }
@Override public boolean isValid( GraphObject object, PropertyKey<String> key, String value, ErrorBuffer errorBuffer) { if (key == null) { return false; } if (StringUtils.isBlank(value)) { errorBuffer.add(object.getType(), new EmptyPropertyToken(key)); return false; } // FIXME: search should be case-sensitive! List<SearchAttribute> attrs = new LinkedList<SearchAttribute>(); attrs.add(Search.andExactName(value)); attrs.add(Search.andType(type)); // just check for existance try { Result nodes = Services.command(securityContext, SearchNodeCommand.class).execute(attrs); if (nodes != null && !nodes.isEmpty()) { return true; } else { errorBuffer.add(object.getType(), new PropertyNotFoundToken(key, value)); return false; } } catch (FrameworkException fex) { // handle error } return false; }
/** * Find first node whose name matches the last part of the given path * * @param securityContext * @param request * @param path * @return * @throws FrameworkException */ private AbstractNode findFirstNodeByName( final SecurityContext securityContext, HttpServletRequest request, final String path) throws FrameworkException { final String name = PathHelper.getName(path); if (!name.isEmpty()) { logger.log(Level.FINE, "Requested name: {0}", name); final Result results = StructrApp.getInstance(securityContext) .nodeQuery() .and(AbstractNode.name, name) .getResult(); logger.log(Level.FINE, "{0} results", results.size()); request.setAttribute(POSSIBLE_ENTRY_POINTS, results.getResults()); return (results.size() > 0 ? (AbstractNode) results.get(0) : null); } return null; }
public void test06DistanceSearchOnEmptyDB() { try { boolean includeDeletedAndHidden = true; boolean publicOnly = false; List<SearchAttribute> searchAttributes = new LinkedList<SearchAttribute>(); searchAttributes.add( new DistanceSearchAttribute( "Hanauer Landstr. 200, 60314 Frankfurt, Germany", 10.0, SearchOperator.AND)); Result result = searchNodeCommand.execute(includeDeletedAndHidden, publicOnly, searchAttributes); assertEquals(0, result.size()); } catch (FrameworkException ex) { logger.log(Level.SEVERE, ex.toString()); System.out.println(ex.toString()); fail("Unexpected exception"); } }
/** * This method checks if the current request is a user registration confirmation, usually * triggered by a user clicking on a confirmation link in an e-mail. * * @param request * @param response * @param path * @return true if the registration was successful * @throws FrameworkException * @throws IOException */ private boolean checkRegistration( final Authenticator auth, final HttpServletRequest request, final HttpServletResponse response, final String path) throws FrameworkException, IOException { logger.log(Level.FINE, "Checking registration ..."); String key = request.getParameter(CONFIRM_KEY_KEY); if (StringUtils.isEmpty(key)) { return false; } String targetPage = request.getParameter(TARGET_PAGE_KEY); String errorPage = request.getParameter(ERROR_PAGE_KEY); if (CONFIRM_REGISTRATION_PAGE.equals(path)) { final App app = StructrApp.getInstance(); Result<Principal> results; try (final Tx tx = app.tx()) { results = app.nodeQuery(Principal.class).and(User.confirmationKey, key).getResult(); } if (!results.isEmpty()) { final Principal user = results.get(0); try (final Tx tx = app.tx()) { // Clear confirmation key and set session id user.setProperty(User.confirmationKey, null); if (auth.getUserAutoLogin()) { AuthHelper.doLogin(request, user); } tx.success(); } // Redirect to target page if (StringUtils.isNotBlank(targetPage)) { response.sendRedirect("/" + targetPage); } return true; } else { // Redirect to error page if (StringUtils.isNotBlank(errorPage)) { response.sendRedirect("/" + errorPage); } return true; } } return false; }
@Override public void execute(Map<String, Object> attributes) throws FrameworkException { final String entityType = (String) attributes.get("type"); final String relType = (String) attributes.get("relType"); final GraphDatabaseService graphDb = (GraphDatabaseService) arguments.get("graphDb"); final SecurityContext superUserContext = SecurityContext.getSuperUserInstance(); final NodeFactory nodeFactory = new NodeFactory(superUserContext); final RelationshipFactory relFactory = new RelationshipFactory(superUserContext); if (entityType != null) { final Class type = EntityContext.getEntityClassForRawType(entityType); if (type != null) { // final Result<AbstractNode> result = Services.command(securityContext, // SearchNodeCommand.class).execute(true, false, Search.andExactType(type.getSimpleName())); final Result<AbstractNode> result = nodeFactory.instantiateAll(GlobalGraphOperations.at(graphDb).getAllNodes()); final List<AbstractNode> nodes = new ArrayList<AbstractNode>(); for (AbstractNode node : result.getResults()) { if (node.getClass().equals(type)) { nodes.add(node); } } logger.log( Level.INFO, "Start (re-)indexing all nodes of type {0}", new Object[] {type.getSimpleName()}); long count = bulkGraphOperation( securityContext, nodes, 1000, "RebuildIndex", new BulkGraphOperation<AbstractNode>() { @Override public void handleGraphObject( SecurityContext securityContext, AbstractNode node) { node.updateInIndex(); } @Override public void handleThrowable( SecurityContext securityContext, Throwable t, AbstractNode node) { logger.log( Level.WARNING, "Unable to index node {0}: {1}", new Object[] {node, t.getMessage()}); } @Override public void handleTransactionFailure( SecurityContext securityContext, Throwable t) { logger.log(Level.WARNING, "Unable to index node: {0}", t.getMessage()); } }); logger.log(Level.INFO, "Done with (re-)indexing {0} nodes", count); return; } } else if (relType != null) { // final Result<AbstractNode> result = Services.command(securityContext, // SearchNodeCommand.class).execute(true, false, Search.andExactType(type.getSimpleName())); final List<AbstractRelationship> unfilteredRels = relFactory.instantiate(GlobalGraphOperations.at(graphDb).getAllRelationships()); final List<AbstractRelationship> rels = new ArrayList<AbstractRelationship>(); for (AbstractRelationship rel : unfilteredRels) { if (!rel.getType().equals(relType)) { rels.add(rel); } } logger.log(Level.INFO, "Start setting UUID on all rels of type {0}", new Object[] {relType}); long count = bulkGraphOperation( securityContext, rels, 1000, "SetRelationshipUuid", new BulkGraphOperation<AbstractRelationship>() { @Override public void handleGraphObject( SecurityContext securityContext, AbstractRelationship rel) { rel.updateInIndex(); } @Override public void handleThrowable( SecurityContext securityContext, Throwable t, AbstractRelationship rel) { logger.log( Level.WARNING, "Unable to index relationship {0}: {1}", new Object[] {rel, t.getMessage()}); } @Override public void handleTransactionFailure(SecurityContext securityContext, Throwable t) { logger.log(Level.WARNING, "Unable to index relationship: {0}", t.getMessage()); } }); logger.log(Level.INFO, "Done with (re-)indexing {0} relationships", count); return; } logger.log(Level.INFO, "Unable to determine entity type to re-index."); }
@Override public List<GraphObject> getData( final SecurityContext securityContext, final RenderContext renderContext, final String restQuery) throws FrameworkException { Map<Pattern, Class<? extends Resource>> resourceMap = new LinkedHashMap<>(); ResourceProvider resourceProvider = renderContext == null ? null : renderContext.getResourceProvider(); if (resourceProvider == null) { try { resourceProvider = UiResourceProvider.class.newInstance(); } catch (Throwable t) { logger.log(Level.SEVERE, "Couldn't establish a resource provider", t); return Collections.EMPTY_LIST; } } // inject resources resourceMap.putAll(resourceProvider.getResources()); Value<String> propertyView = new ThreadLocalPropertyView(); propertyView.set(securityContext, PropertyView.Ui); // initialize variables // mimic HTTP request HttpServletRequest request = new HttpServletRequestWrapper( renderContext == null ? securityContext.getRequest() : renderContext.getRequest()) { @Override public Enumeration<String> getParameterNames() { return new IteratorEnumeration(getParameterMap().keySet().iterator()); } @Override public String getParameter(String key) { String[] p = getParameterMap().get(key); return p != null ? p[0] : null; } @Override public Map<String, String[]> getParameterMap() { String[] parts = StringUtils.split(getQueryString(), "&"); Map<String, String[]> parameterMap = new HashMap(); for (String p : parts) { String[] kv = StringUtils.split(p, "="); if (kv.length > 1) { parameterMap.put(kv[0], new String[] {kv[1]}); } } return parameterMap; } @Override public String getQueryString() { return StringUtils.substringAfter(restQuery, "?"); } @Override public String getPathInfo() { return StringUtils.substringBefore(restQuery, "?"); } @Override public StringBuffer getRequestURL() { return new StringBuffer(restQuery); } }; // update request in security context securityContext.setRequest(request); // HttpServletResponse response = renderContext.getResponse(); Resource resource = ResourceHelper.applyViewTransformation( request, securityContext, ResourceHelper.optimizeNestedResourceChain( ResourceHelper.parsePath( securityContext, request, resourceMap, propertyView, GraphObject.id), GraphObject.id), propertyView); // TODO: decide if we need to rest the REST request here // securityContext.checkResourceAccess(request, resource.getResourceSignature(), // resource.getGrant(request, response), PropertyView.Ui); // add sorting & paging String pageSizeParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_SIZE); String pageParameter = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_PAGE_NUMBER); String offsetId = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_OFFSET_ID); String sortOrder = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_ORDER); String sortKeyName = request.getParameter(JsonRestServlet.REQUEST_PARAMETER_SORT_KEY); boolean sortDescending = (sortOrder != null && "desc".equals(sortOrder.toLowerCase())); int pageSize = parseInt(pageSizeParameter, NodeFactory.DEFAULT_PAGE_SIZE); int page = parseInt(pageParameter, NodeFactory.DEFAULT_PAGE); PropertyKey sortKey = null; // set sort key if (sortKeyName != null) { Class<? extends GraphObject> type = resource.getEntityClass(); if (type == null) { // fallback to default implementation // if no type can be determined type = AbstractNode.class; } sortKey = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(type, sortKeyName); } // do action Result result = resource.doGet(sortKey, sortDescending, pageSize, page, offsetId); result.setIsCollection(resource.isCollectionResource()); result.setIsPrimitiveArray(resource.isPrimitiveArray()); // Integer rawResultCount = (Integer) Services.getAttribute(NodeFactory.RAW_RESULT_COUNT + // Thread.currentThread().getId()); PagingHelper.addPagingParameter(result, pageSize, page); List<GraphObject> res = result.getResults(); if (renderContext != null) { renderContext.setResult(result); } return res != null ? res : Collections.EMPTY_LIST; }
@Override public void postProcessResultSet(Result result) { result.setSortOrder(sortOrder); result.setSortKey(sortKey); }