Jackrabbit - node.getReferences() not returning anything - reference

I'm trying to add a reference but when I call node.getReferences() I can't see it.
I've tried creating a simple example -> create 2 nodes under root and reference one from the other. That works fine.
In my working code it doesn't. I'm guessing it's got something to do with versioning but I can' find any doc's explaining what's going on. Let me explain the structure
Root
|__project node
|
|__ node 1
|
|__ node 2
All nodes have mix:versionable and mix:referenceble.
Bit of code...
node1.checkout();
node2.checkout();
node2.setProperty("ref to node1", node1);
session.save();
if (!node1.getReferences().hasNext())
System.out.println("No references");
I've tried removing the checkout's and the save but all to no avail.
Any comments or recommended reading appreciated.
Ted.

The code you listed should work as you expect. Are you using some remoting layer (RMI, WebDAV, etc.) that might have a bug in the way references are handled?
You can try for example the following code with a local Jackrabbit instance:
Node root = session.getRootNode().addNode("test");
Node node1 = root.addNode("node1");
node1.addMixin("mix:referenceable");
Node node2 = root.addNode("node2");
node2.setProperty("reference", node1);
session.save();
System.out.println("References to " + node1.getPath() + ":");
for (Property reference : JcrUtils.getReferences(node1)) {
System.out.println("- " + reference.getPath());
}
It prints out the following:
References to /test/node1:
- /test/node2/reference

Related

Running "module.exports = function(foo){...}" in Node vm2

I'm new to Node and the virtual machine vm2. In the documentation for the latter, it gives an example of its usage:
let functionInSandbox = vm.run("module.exports = function(who) { console.log('hello '+ who); }");
functionInSandbox('world');
Question: what is this actually doing?
Firstly, why is module.exports used here at all? Ie, why not omit it as below?
let functionInSandbox = vm.run("function(who) { console.log('hello '+ who); }");
functionInSandbox('world');
Secondly, another way of looking at it: in regular node programming, it is beginner's knowledge that require(inc) is used in one file to assign to a variable, what, in another file (chosen by inc), is assigned to module.exports. How is that different to the above usage with vm2?
Specifically: is require(...) being implicitly called in the above? How could multiple modules be defined (as above) and referred to, within one sandbox?
It's hard to know what questions to even ask - really I'm just hoping for an explanation of ways in which module.exports can be used with vm2 in ways that differ to regular node programming, highlighting differences.

Adjusting AVAudioMix volume property has no effect in iOS9

I have an app which loads local files into an avPlayer via a AVMutableComposition, it may have as many as 6 audio and video tracks as part of the composition.
I have a UISlider which is used to adjust the volume of each track in the player.
Below is the code used to update the volume.
- (void)updateVolumeForTake:(Take *)take
{
NSInteger trackID = // method that gets trackID
AVMutableAudioMix *audioMix = self.player.currentItem.audioMix.mutableCopy;
NSMutableArray *inputParameters = audioMix.inputParameters.mutableCopy;
AVMutableAudioMixInputParameters *audioInputParams = [inputParameters filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:kTrackIdPredicate, trackID]].firstObject;
[audioInputParams setVolume:myNewVolumeFloat atTime:myDesiredTime];
audioMix.inputParameters = inputParameters;
AVPlayerItem *playerItem = self.player.currentItem;
playerItem.audioMix = audioMix;
}
This is is currently live in the appStore and has been since iOS6 and has always worked with no issue.
On a device running iOS9, the above no longer works at all. I have looked at the release notes and although there is some mention of AVFoundation, I didn't see anything regarding AVAudioMix.I have googled around and have not found anyone else with this issue.
I also tried creating a new project with nothing but an AVPlayer and UISlider and I saw the same behaviour.
My question is as follows, has anyone else experienced this issue?
Is anyone aware of a known bug related to this?
I have found a solution but unfortunately not an exact cause.
I can't say I fully understand why this fixed my issue but here is the solution and an attempt at explaining why it fixed the issue I was experiencing.
- (void)updateVolumeForTake:(Take *)take
{
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
NSMutableArray *inputParameters = [self.inputParameters filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:kNotTrackIdPredicate, myTrackID]].mutableCopy;
AVCompositionTrack *track = (AVCompositionTrack *)[self.composition trackWithTrackID:myTrackID];
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track];
[audioInputParams setVolume:myDesiredVolume atTime:kCMTimeZero];
[inputParameters addObject:audioInputParams];
audioMix.inputParameters = inputParameters;
AVPlayerItem *playerItem = self.player.currentItem;
playerItem.audioMix = audioMix;
self.inputParameters = inputParameters;
}
As you can see above, I have stopped using mutable copies of my AVAudioMix and its inputParameters and instead created a new AVAudioMix and NSMutableArray for inputParameters. The new inputParameters array is a copy of the existing inputParameters (referenced from a property 'self.inputParameters') minus the track matching the one I wish to change.
Secondly I create a new instance of AVMutableAudioMixInputParameters using the track with which I wish to edit the volume of (previously I was getting reference to the existing params with matching trackID and modifying them). I edit that add it to my new array and make that the audio mix of currentItem.
Again I can't say with any certainty why this fixes it, but it did for me, I wonder if all the mutable copies were not being discovered as different at all when I reassigned the audioMix of the playerItem and thats why I didn't hear any change in the volume. (although this seems doubtful).
Anyway my issue is fixed and I hope this can help anyone who has a similar issue.

Standalone PHP script using Expression Engine

Is there a way to make a script where I can do stuff like $this->EE->db (i.e. using Expression Engine's classes, for example to access the database), but that can be run in the command line?
I tried searching for it, but the docs don't seem to contain this information (please correct me if I'm wrong). I'm using EE 2.4 (the link above should point to 2.4 docs).
The following article seems to have a possible approach: Bootstrapping EE for CLI Access
Duplicate your index.php file and name it cli.php.
Move the index.php file outside your DOCUMENT_ROOT. Now, technically, this isn’t required, but there’s no reason for prying
eyes to see your hard work so why not protect it.
Inside cli.php update the $system_path on line 26 to point to your system folder.
Inside cli.php update the $routing['controller'] on line 96 to be cli.
Inside cli.php update the APPPATH on line 96 to be $system_path.'cli/'.
Duplicate the system/expressionengine directory and name it system/cli.
Duplicate the cli/controllers/ee.php file and name it cli/controllers/cli.php.
Finally, update the class name in cli/controllers/cli.php to be Cli and remove the methods.
By default EE calls the index method, so add in an index method to do what you need.
#Zenbuman This was useful as a starting point although I would add I had issues with all of my requests going to cli -> index, whereas I wanted some that went to cli->task1, cli->task2 etc
I had to update *system\codeigniter\system\core\URI.php*so that it knew how to extract the parameters I was passing via the command line, I got the code below from a more recent version of Codeigniter which supports the CLI
// Is the request coming from the command line?
if (php_sapi_name() == 'cli' or defined('STDIN'))
{
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// Let's try the REQUEST_URI first, this will work in most situations
and also created the function in the same file
private function _parse_cli_args()
{
$args = array_slice($_SERVER['argv'], 1);
return $args ? '/' . implode('/', $args) : '';
}
Also had to comment out the following in my cli.php file as all routing was going to the index method in my cli controller and ignoring my parameters
/*
* ~ line 109 - 111 /cli.php
* ---------------------------------------------------------------
* Disable all routing, send everything to the frontend
* ---------------------------------------------------------------
*/
$routing['directory'] = '';
$routing['controller'] = 'cli';
//$routing['function'] = '';
Even leaving
$routing['function'] = '';
Will force requests to go to index controller
In the end I felt this was a bit hacky but I really need to use the EE API library in my case. Otherwise I would have just created a separate application with Codeigniter to handle my CLI needs, hope the above helps others.
I found #Zenbuman's answer after solving my own variation of this problem. My example allows you to keep the cron script inside a module, so if you need your module to have a cron feature it all stays neatly packaged together. Here's a detailed guide on my blog.

How do I support multiple server.pid files?

I am running play on multiple machines in our datacenter. We loadbalance the hell out of everything. On each play node/VM I'm using Apache and an init.d/play script to start and stop the play service.
The problem is that our play websites are hosted on shared network storage. This makes deployment really nice, you deploy to one place and the website is updated on all 100 machines. Each machine has a mapped folder "/z/www/PlayApp1" where the play app lives.
The issue is that when the service starts or stops the server.pid file is being written to that network location where the apps files live.
The problem is that as I bring up 100 nodes, the 100th node will override the PID file with it's pid and now that pid file only represents the correct process ID for 1 out of 100 nodes.
So how do I get play to store the pid file locally and not with the app files on the network share? I'll need each server's PID file to reflect that machines actual process.
We are using CentOS (Linux)
Thanks in advance
Josh
According to https://github.com/playframework/play/pull/43 it looks like there is a --pid_file command line option; it might only work with paths under the application root so you might have to make directories for each distinct host (which could possibly be symlinks)
I have 0 experience with Play so hopefully this is helpful information.
I don't even think it should run a second copy, based on the current source code. The main function is:
public static void main(String[] args) throws Exception {
File root = new File(System.getProperty("application.path"));
if (System.getProperty("precompiled", "false").equals("true")) {
Play.usePrecompiled = true;
}
if (System.getProperty("writepid", "false").equals("true")) {
writePID(root);
}
:
blah blah blah
}
and writePID is:
private static void writePID(File root) {
String pid = ManagementFactory.getRuntimeMXBean().getName().split("#")[0];
File pidfile = new File(root, PID_FILE);
if (pidfile.exists()) {
throw new RuntimeException("The " + PID_FILE + " already exists. Is the server already running?");
}
IO.write(pid.getBytes(), pidfile);
}
meaning it should throw an exception when you try to run multiple copies using the same application.path.
So either you're not using the version I'm looking at or you're discussing something else.
It seems to me it would be a simple matter to change that one line above:
File root = new File(System.getProperty("application.path"));
to use a different property for the PID file storage, one that's not on the shared drive.
Although you'd need to be careful, root is also passed to Play.int so you should investigate the impact of changing it.
This is, after all, one of the great advantages of open source software, inasmuch as you can fix the "bugs" yourself.
For what it's worth, I'm not a big fan of the method you've chosen for deployment. Yes, it simplifies deployment but upgrading your servers is an all-or-nothing thing which will cause you grief if you accidentally install some dodgy software.
I much prefer staged deployments so I can shut down non-performing nodes as needed.
Change your init script to write the pid to /tmp or somewhere else machine-local.
If that is hard, a symlink might work.

node.js - eval'ing to a live process

Did anyone set up something like this for himself using the existing
node.js REPL? I didn't think of a quick way to do it.
The way I do it today is using emacs and this:
https://github.com/ivan4th/swank-js
This module is composed of:
A SLIME-js addon to emacs which, in combination with js2-mode, lets
you simply issue a C-M-x somewhere in the body of a function def - and
off goes the function's string to the ..
Swank-js server (yes, you could eval from your local-machine
directly to a remote process) written in Node.js - It receives the
string of the function you eval'ed and actually evals it
A whole part that lets you connect to another port on that server
with your BROWSER and then lets you manipulate the DOM on that browser
(which is pretty amazing but not relevant)
My solution uses SLIME-js on the emacs side AND I require('swank-
js') on my app.js file
Now.. I have several issues and questions regarding my solution or
other possible ones:
Q1: Is this overdoing it? Does someone have a secret way to eval stuff
from nano into his live process?
Q2: I had to change the way swank-js is EVALing.. it used some
kind of black magic like this:
var Script = process.binding('evals').Script;
var evalcx = Script.runInContext;
....
this.context = Script.createContext();
for (var i in global) this.context[i] = global[i];
this.context.module = module;
this.context.require = require;
...
r = evalcx("CODECODE", this.context, "repl");
which, as far I understand, just copies the global variables to the
new context, and upon eval, doesn't change the original function
definitions - SOOO.. I am just using plain "eval" and IT
WORKS.
Do you have any comments regarding this?
Q3: In order to re-eval a function, it needs to be a GLOBAL function -
Is it bad practice to have all function definitions as global (clojure-like) ? Do you think there is another way to do this?
Actually, swank.js is getting much better, and it is now much easier to set up swank js with your project using NPM. I'm in the process of writing the documentation right now, but the functionality is there!
Check this out http://nodejs.org/api/vm.html
var util = require('util'),
vm = require('vm'),
sandbox = {
animal: 'cat',
count: 2
};
vm.runInNewContext('count += 1; name = "kitty"', sandbox, 'myfile.vm');
console.log(util.inspect(sandbox));
// { animal: 'cat', count: 3, name: 'kitty' }
Should help you a lot, all of the sandbox things for node uses it :) but you can use it directly :)
You might take a look at jsapp.us, which runs JS in a sandbox, and then exposes that to the world as a quick little test server. Here's the jsapp.us github repo.
Also, stop into #node.js and ask questions for a quicker response :)

Resources