use of org.structr.web.entity.dom.DOMNode in project structr by structr.
the class XPathGraphDataSource method getData.
@Override
public Iterable<GraphObject> getData(final RenderContext renderContext, final DOMNode referenceNode) throws FrameworkException {
final String xpathQuery = referenceNode.getXpathQuery();
if (StringUtils.isBlank(xpathQuery)) {
return null;
}
final Document document = ((DOMNode) referenceNode).getOwnerDocument();
final XPathFactory factory = XPathFactory.newInstance();
final XPath xpath = factory.newXPath();
try {
// FIXME: this code works only with absolute xpath queries because
// the xpath parser implementation is stupid (comparing object
// equality using ==).
Object result = xpath.evaluate(xpathQuery, document, XPathConstants.NODESET);
List<GraphObject> results = new LinkedList<>();
if (result instanceof NodeList) {
NodeList nodes = (NodeList) result;
int len = nodes.getLength();
for (int i = 0; i < len; i++) {
Node node = nodes.item(i);
if (node instanceof GraphObject) {
results.add((GraphObject) node);
}
}
} else if (result instanceof GraphObject) {
results.add((GraphObject) result);
}
return results;
} catch (Throwable t) {
logger.warn("Unable to execute xpath query: {}", t.getMessage());
}
return Collections.EMPTY_LIST;
}
use of org.structr.web.entity.dom.DOMNode in project structr by structr.
the class MoveOperation method apply.
// ----- interface InvertibleModificationOperation -----
@Override
public void apply(final App app, final Page sourcePage, final Page newPage) throws FrameworkException {
final InsertPosition insertPosition = findInsertPosition(sourcePage, parentHash, siblingHashes, newNode);
if (insertPosition != null) {
final DOMNode parent = insertPosition.getParent();
final DOMNode sibling = insertPosition.getSibling();
final Node originalSibling = originalNode.getNextSibling();
final Node originalParent = originalNode.getParentNode();
// do not modify synced nodes (nodes that are shared between multiple pages)
if (parent.isSynced()) {
return;
}
if (parent.equals(originalParent)) {
if (sibling != null && sibling.equals(originalSibling)) {
// nothing to be done
return;
}
if (sibling == null && originalSibling == null) {
return;
}
}
// the following code tries to insert the original node next to
// its original sibling. If there is no sibling (since the node
// was moved up or down, this method tries to insert the new
// node next to its sibling's parent, ascending the tree until
// no parents are left.
Node localSibling = sibling;
boolean found = false;
int count = 0;
while (localSibling != null && count++ < 10) {
try {
parent.insertBefore(originalNode, localSibling);
found = true;
break;
} catch (DOMException dex) {
}
// ascend to parent
localSibling = localSibling.getParentNode();
}
// try direct insertion
if (!found) {
parent.appendChild(originalNode);
}
}
}
use of org.structr.web.entity.dom.DOMNode in project structr by structr.
the class IncludeFunction method apply.
@Override
public Object apply(final ActionContext ctx, final Object caller, final Object[] sources) throws FrameworkException {
try {
if (!(arrayHasMinLengthAndAllElementsNotNull(sources, 1) && sources[0] instanceof String)) {
return null;
}
final PropertyKey<DOMNode> sharedCompKey = StructrApp.key(DOMNode.class, "sharedComponent");
final SecurityContext securityContext = ctx.getSecurityContext();
final App app = StructrApp.getInstance(securityContext);
final RenderContext innerCtx = new RenderContext((RenderContext) ctx);
final List<DOMNode> nodeList = app.nodeQuery(DOMNode.class).andName((String) sources[0]).getAsList();
DOMNode node = null;
/**
* Nodes can be included via their name property These nodes MUST: 1. be unique in name 2. NOT be in the trash => have an ownerDocument AND a parent (public
* users are not allowed to see the __ShadowDocument__ ==> this check must either be made in a superuser-context OR the __ShadowDocument could be made public?)
*
* These nodes can be: 1. somewhere in the pages tree 2. in the shared components 3. both ==> causes a problem because we now have multiple nodes with the same
* name (one shared component and multiple linking instances of that component)
*
* INFOS:
*
* - If a DOMNode has "syncedNodes" it MUST BE a shared component - If a DOMNodes "sharedComponent" is set it MUST BE AN INSTANCE of a shared component => Can
* we safely ignore these? I THINK SO!
*/
for (final DOMNode n : nodeList) {
if (n.inTrash()) {
continue;
}
// IGNORE everything that REFERENCES a shared component!
if (n.getProperty(sharedCompKey) == null) {
// the DOMNode is either a shared component OR a named node in the pages tree
if (node == null) {
node = n;
} else {
// TODO: Do we need to remove the nodes from the nodeList which can be ignored? (references to a shared component)
return "Ambiguous node name \"" + ((String) sources[0]) + "\" (nodes found: " + StringUtils.join(nodeList, ", ") + ")";
}
}
}
if (node != null) {
if (sources.length == 3 && sources[1] instanceof Iterable && sources[2] instanceof String) {
final Iterable<GraphObject> iterable = FunctionDataSource.map((Iterable) sources[1]);
final String dataKey = (String) sources[2];
innerCtx.setListSource(iterable);
node.renderNodeList(securityContext, innerCtx, 0, dataKey);
} else {
node.render(innerCtx, 0);
}
if (innerCtx.appLibRendered()) {
((RenderContext) ctx).setAppLibRendered(true);
}
} else {
final File file = app.nodeQuery(File.class).andName((String) sources[0]).getFirst();
if (file != null) {
final String name = file.getProperty(NodeInterface.name);
final String contentType = file.getContentType();
final String charset = StringUtils.substringAfterLast(contentType, "charset=");
final String extension = StringUtils.substringAfterLast(name, ".");
if (contentType == null || StringUtils.isBlank(extension)) {
logger.warn("No valid file type detected. Please make sure {} has a valid content type set or file extension. Parameters: {}", new Object[] { name, getParametersAsString(sources) });
return "No valid file type detected. Please make sure " + name + " has a valid content type set or file extension.";
}
if (contentType.startsWith("text/css")) {
return "<link href=\"" + file.getPath() + "\" rel=\"stylesheet\">";
} else if (contentType.contains("/javascript")) {
return "<script src=\"" + file.getPath() + "\"></script>";
} else if (contentType.startsWith("image/svg")) {
try (final InputStream is = file.getInputStream()) {
final byte[] buffer = new byte[file.getSize().intValue()];
IOUtils.read(is, buffer);
return StringUtils.toEncodedString(buffer, Charset.forName(charset));
} catch (IOException ex) {
logger.warn("Exception for parameters: {}", getParametersAsString(sources));
logger.error("", ex);
}
return "<img alt=\"" + name + "\" src=\"" + file.getPath() + "\">";
} else if (contentType.startsWith("image/")) {
return "<img alt=\"" + name + "\" src=\"" + file.getPath() + "\">";
} else {
logger.warn("Don't know how to render content type or extension of {}. Parameters: {}", new Object[] { name, getParametersAsString(sources) });
return "Don't know how to render content type or extension of " + name + ".";
}
}
}
return StringUtils.join(innerCtx.getBuffer().getQueue(), "");
} catch (final IllegalArgumentException e) {
logParameterError(caller, sources, ctx.isJavaScriptContext());
return usage(ctx.isJavaScriptContext());
}
}
use of org.structr.web.entity.dom.DOMNode in project structr by structr.
the class DeploymentTest method test16SharedTemplateWithChildren.
@Test
public void test16SharedTemplateWithChildren() {
// setup
try (final Tx tx = app.tx()) {
final Page page = Page.createNewPage(securityContext, "test16");
final Html html = createElement(page, page, "html");
final Head head = createElement(page, html, "head");
createElement(page, head, "title", "test16");
final Body body = createElement(page, html, "body");
final Div div1 = createElement(page, body, "div");
final Template template = createTemplate(page, div1, "template source - öäüÖÄÜß'\"'`");
createElement(page, template, "div");
final DOMNode table = createElement(page, template, "table");
final DOMNode tr = createElement(page, table, "tr");
createElement(page, tr, "td");
createElement(page, tr, "td");
createComponent(template);
tx.success();
} catch (FrameworkException fex) {
fail("Unexpected exception.");
}
// test
compare(calculateHash(), true, false);
}
use of org.structr.web.entity.dom.DOMNode in project structr by structr.
the class DeploymentTest method hash.
private void hash(final NodeInterface node, final StringBuilder buf) {
// AbstractNode
buf.append(valueOrEmpty(node, AbstractNode.type));
buf.append(valueOrEmpty(node, AbstractNode.name));
buf.append(valueOrEmpty(node, AbstractNode.visibleToPublicUsers));
buf.append(valueOrEmpty(node, AbstractNode.visibleToAuthenticatedUsers));
// include owner in content hash generation!
final Principal owner = node.getOwnerNode();
if (owner != null) {
buf.append(valueOrEmpty(owner, AbstractNode.name));
}
// include grants in content hash generation!
for (final Security r : node.getSecurityRelationships()) {
if (r != null) {
buf.append(r.getSourceNode().getName());
buf.append(r.getPermissions());
}
}
// DOMNode
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "showConditions")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideConditions")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "showForLocales")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideForLocales")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideOnIndex")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideOnDetail")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "renderDetails")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "sharedComponentConfiguration")));
if (node instanceof DOMNode) {
final Page ownerDocument = ((DOMNode) node).getOwnerDocument();
if (ownerDocument != null) {
buf.append(valueOrEmpty(ownerDocument, AbstractNode.name));
}
}
// DOMElement
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "dataKey")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "restQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "cypherQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "xpathQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "functionQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-reload")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-confirm")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-action")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-attributes")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-attr")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-name")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-hide")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-raw-value")));
// Content
buf.append(valueOrEmpty(node, StructrApp.key(Content.class, "contentType")));
buf.append(valueOrEmpty(node, StructrApp.key(Content.class, "content")));
// Page
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "cacheForSeconds")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "dontCache")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "pageCreatesRawData")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "position")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "showOnErrorCodes")));
// HTML attributes
if (node instanceof DOMElement) {
for (final PropertyKey key : ((DOMElement) node).getHtmlAttributes()) {
buf.append(valueOrEmpty(node, key));
}
}
for (final PropertyKey key : node.getPropertyKeys(PropertyView.All)) {
if (!key.isPartOfBuiltInSchema()) {
buf.append(valueOrEmpty(node, key));
}
}
}
Aggregations