How do I programmatically know which run-mode the instance is running? I created a custom tag that provides the config depending on the instance run-mode, but I can not determine the current run-mode.
I found a method that returns a list of run-mods instance:
SlingSettings settings = ...get from BundleContext...
Set<String> currentRunModes = settings.getRunModes();
But I can not get the objects SlingSettings or BundleContext. How can I get these objects or perhaps there is another way to get the current run-mode?
SlingSetttings is the right way - If it's from Java the simplest way to get it is with an SCR #Reference annotation in a class that's an SCR #Component, saves you from having to go through BundleContext.
If it's from a Sling script, you can use sling.getService(....) to get the SlingSettings.
Note that the cases where you need to read the run modes are rare, usually you'd rather setup your OSGi configurations to depend on the run modes and have the OSGi components modify their behavior based on that.
Finally I decided to use global.jsp, write run-modes in the page context and get it in my class:
<%
pageContext.setAttribute("runModes", sling.getService(SlingSettingsService.class).getRunModes().toString());
%>
import java.util.Set;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.apache.sling.settings.SlingSettingsService;
public class myClass {
public static Set<String> getRunModes() {
BundleContext bundleContext = FrameworkUtil.getBundle(myClass.class).getBundleContext();
ServiceReference serviceReference = bundleContext.getServiceReference(SlingSettingsService.class.getName( ));
SlingSettingsService slingSettingsService = (SlingSettingsService)bundleContext.getService(serviceReference);
return slingSettingsService.getRunModes();
}
}
#Reference
RunMode runmode;
or
sling.getService( RunMode.class )
and call
getCurrentRunModes(); //returns String[]
If you're using Sightly and working with a class that extends WCMUsePojo
slingSettings =this.getSlingScriptHelper().getService(SlingSettingsService.class);
Set<String> runmodes = slingSettings.getRunModes();
As Bertrand Delacretaz said it is the right way to check whether instance is Author or Publish.
In jsp or java you could check like
import org.apache.sling.settings.SlingSettingsService
Set<String> runModes = sling.getService(SlingSettingsService.class).getRunModes();
if (runModes.contains("author")) {
}
Another way is using
if (mode == WCMMode.EDIT)
{
}
But this approach will fail in case of Preview mode and wouldn't work.
You can also try this:
RunModeService runModeService = getSlingScriptHelper().getService(RunModeService.class);
author = runModeService.isActive("author");
Related
actually I would to retrieve two params from the #ManagedService path, but i get only null value.
The code is something like:
...
import org.atmosphere.config.service.PathParam;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Singleton;
#Singleton
#ManagedService(path = "/chat/{myId}/{destId}")
public class Chat {
#PathParam("myId")
private String mittId;
#PathParam("destId")
private String destId;
#Ready
public void onReady(AtmosphereResource r) {
logger.info("User {} want to chat with {}", mittId,destId);
}
Debugging "mittId" and "destId" are null.
There's some error on the code or something that I forget?
Actually I'm using Atmosphere-runtime 2.3.0.
Thanks to anybody that will help!
The client is correct. I resolve removing #Singleton annotation. Now while I'm debugging I can see the value of the two params.
Either you are not sharing the enough or the original back-end code or your client application is calling the chat resource incorrectly.
I tested your example and both path parameters are populated.
Please have a look at the example in the Atmosphere Github page about the the multichatroom, especially the client implementation.
Does anyone have a good way to unit test an entity's validation constraints in Symfony2?
Ideally I want to have access to the Dependency Injection Container within the unit test which would then give me access to the validator service. Once I have the validator service I can run it manually:
$errors = $validator->validate($entity);
I could extend WebTestCase and then create a client to get to the container as per the docs however it doesn't feel right. The WebTestCase and client read in the docs as more of a facility to test actions as a whole and therefore it feels broken to use it to unit test an entity.
So, does anyone know how to either a) get the container or b) create the validator inside a unit test?
Ok since this got two votes I guess other people are interested.
I decided to get my shovel out and was pleasantly surprised (so far anyway) that this wasn't at all difficult to pull off.
I remembered that each Symfony2 component can be used in a stand alone mode and therefore that I could create the validator myself.
Looking at the docs at: https://github.com/symfony/Validator/blob/master/ValidatorFactory.php
I realised that since there was a ValidatorFactory it was trivial to create a validator (especially for validation done by annotations which I am, although if you look at the docblock on the page I linked above you'll also find ways to validate xml and yml).
First:
# Symfony >=2.1
use Symfony\Component\Validator\Validation;
# Symfony <2.1
use Symfony\Component\Validator\ValidatorFactory;
and then:
# Symfony >=2.1
$validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
# Symfony <2.1
$validator = ValidatorFactory::buildDefault()->getValidator();
$errors = $validator->validate($entity);
$this->assertEquals(0, count($errors));
I hope this helps anyone else whose conscience wouldn't allow them to just use WebTestCase ;).
We end up rolling your own base test case to access the dependency container from within a test case. Here the class in question:
<?php
namespace Application\AcmeBundle\Tests;
// This assumes that this class file is located at:
// src/Application/AcmeBundle/Tests/ContainerAwareUnitTestCase.php
// with Symfony 2.0 Standard Edition layout. You may need to change it
// to fit your own file system mapping.
require_once __DIR__.'/../../../../app/AppKernel.php';
class ContainerAwareUnitTestCase extends \PHPUnit_Framework_TestCase
{
protected static $kernel;
protected static $container;
public static function setUpBeforeClass()
{
self::$kernel = new \AppKernel('dev', true);
self::$kernel->boot();
self::$container = self::$kernel->getContainer();
}
public function get($serviceId)
{
return self::$kernel->getContainer()->get($serviceId);
}
}
With this base class, you can now do this in your test methods to access the validator service:
$validator = $this->get('validator');
We decided to go with a static function instead of the class constructor but you could easily change the behavior to instantiate the kernel into the constructor directly instead of relying on the static method setUpBeforeClass provided by PHPUnit.
Also, keep in mind that each single test method in you test case won't be isolated fro, each others because the container is shared for the whole test case. Making modification to the container may have impact on you other test method but this should not be the case if you access only the validator service. However, this way, the test cases will run faster because you will not need to instantiate and boot a new kernel for each test methods.
For the sake of reference, we find inspiration for this class from this blog post. It is written in French but I prefer to give credit to whom it belongs :)
Regards,
Matt
I liked Kasheens answer, but it doesn't work for Symfony 2.3 anymore.
There are little changes:
use Symfony\Component\Validator\Validation;
and
$validator = Validation::createValidatorBuilder()->getValidator();
If you want to validate Annotations for instance, use enableAnnotationMapping() like below:
$validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
the rest stays the same:
$errors = $validator->validate($entity);
$this->assertEquals(0, count($errors));
With Symfony 2.8, it seems that you can now use the AbstractConstraintValidatorTest class this way :
<?php
namespace AppBundle\Tests\Constraints;
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
use AppBundle\Constraints\MyConstraint;
use AppBundle\Constraints\MyConstraintValidator;
use AppBundle\Entity\MyEntity;
use Symfony\Component\Validator\Validation;
class MyConstraintValidatorTest extends AbstractConstraintValidatorTest
{
protected function getApiVersion()
{
return Validation::API_VERSION_2_5;
}
protected function createValidator()
{
return new MyConstraintValidator();
}
public function testIsValid()
{
$this->validator->validate(null, new MyEntity());
$this->assertNoViolation();
}
public function testNotValid()
{
$this->assertViolationRaised(new MyEntity(), MyConstraint::SOME_ERROR_NAME);
}
}
You have got a good sample with the IpValidatorTest class
The answer in https://stackoverflow.com/a/41884661/4560833 has to be changed a little for Symfony 4:
Use ConstraintValidatorTestCase instead of AbstractConstraintValidatorTest.
Answer (b): Create the Validator inside the Unit Test (Symfony 2.0)
If you built a Constraint and a ConstraintValidator you don't need any DI container at all.
Say for example you want to test the Type constraint from Symfony and it's TypeValidator. You can simply do the following:
use Symfony\Component\Validator\Constraints\TypeValidator;
use Symfony\Component\Validator\Constraints\Type;
class TypeValidatorTest extends \PHPUnit_Framework_TestCase
{
function testIsValid()
{
// The Validator class.
$v = new TypeValidator();
// Call the isValid() method directly and pass a
// configured Type Constraint object (options
// are passed in an associative array).
$this->assertTrue($v->isValid(5, new Type(array('type' => 'integer'))));
$this->assertFalse($v->isValid(5, new Type(array('type' => 'string'))));
}
}
With this you can check every validator you like with any constraint configuration. You neither need the ValidatorFactory nor the Symfony kernel.
Update: As #psylosss pointed out, this doesn't work in Symfony 2.5. Nor does it work in Symfony >= 2.1. The interface from ConstraintValidator got changed: isValid was renamed to validate and doesn't return a boolean anymore. Now you need an ExecutionContextInterface to initialize a ConstraintValidator which itself needs at least a GlobalExecutionContextInterface and a TranslatorInterface... So basically it's not possible anymore without way too much work.
I don't see a problem with the WebTestCase. If you don't want a client, don't create one ;) But using a possibly different service than your actual application will use, that's a potential pit fall. So personally, I've done like this:
class ProductServiceTest extends Symfony\Bundle\FrameworkBundle\Test\WebTestCase
{
/**
* Setup the kernel.
*
* #return null
*/
public function setUp()
{
$kernel = self::getKernelClass();
self::$kernel = new $kernel('dev', true);
self::$kernel->boot();
}
public function testFoo(){
$em = self::$kernel->getContainer()->get('doctrine.orm.entity_manager');
$v = self::$kernel->getContainer()->get('validator');
// ...
}
}
It's less DRY than Matt answer -- as you'll repeat the code (for each test class) and boot the kernel often (for each test method), but it's self-contained and require no extra dependencies, so it depends on your needs. Plus I got rid of the static require.
Also, you're sure to have the same services that your application is using -- not default or mock, as you boot the kernel in the environnement that you wish to test.
If people still read this one in 2023, prefer to inject the ValidatorInterface for Symfony > 3 / 4.
use Symfony\Component\Validator\Validator\ValidatorInterface;
// ...
$this->validator->validate($myEntity);
I've got an object declared and instantiated in my Flex application's singular MXML file:
public var CDN:CDNClass = new CDNClass;
I would like to access this same CDN object (and its public methods and properties) in another class declared in a separate .as file as such:
package my.vp
{
import my.media.CDNClass;
public class SyncConnectorManager
{
private function syncMessageReceived(p_evt:SyncSwfEvent):void
{
switch (p_evt.data.msgNm)
{
case "startStream" :
// Play a stream
CDN.parsePlayList(p_evt.data.msgVal);
break;
But when I try to access the public method parsePlayList in the CDN object in a method in the class defined in the .as file, I get the following error:
Access of undefined property CDN
The reason I want to do this is to break up the logic of my application into multiple AS files and have minimal MXML files, probably only one.
Thanks - any help is much appreciated. Perhaps my OOD/OOP thinking is not correct here?
IT depends on your class architecture. For your code to work, the CDNClass instance must be defined and implemented inside your SyncConnectorManager.
Generally, you can always call down into components, but should never call up
One option is to pass the instance ofCDNClass to a variable inside SyncConnectorManager. Add this variable to your SyncConnectionManager class:
public var CDN:CDNClass = new CDNClass;
And at some point do this:
syncConnectorManagerInstance.CDN = CDN;
That way both classes will have access to the same CDN instance and can call methods on it.
Yes, your OOP thinking is not correct here. You should take in mind differences between classes and instances. This line declares a filed in a current class and initiates it with an instance:
public var CDN:CDNClass = new CDNClass;
So current instance of your MXML class (you can think about it as usual AS class with some other notation) has public field. To operate with CDN instance you need something from the following:
Read the value of CDN (as far as it is public) from the instance of your MXML class. You need some reference to it for that.
The instance of your MXML class can have a reference to the instance of SyncConnectorManager and SyncConnectorManager should have a way to inject the value of CDN there. Something like:
Your class:
package my.vp
{
import my.media.CDNClass;
public class SyncConnectorManager
{
private var CDN:CDNClass;
public function SyncConnectorManager(CDN:CDNClass)
{
this.CDN = CDN;
}
private function syncMessageReceived(p_evt:SyncSwfEvent):void
{
switch (p_evt.data.msgNm)
{
case "startStream" :
// Play a stream
CDN.parsePlayList(p_evt.data.msgVal);
break;
In your case SyncConnectorManager class hasn't CDN declared (the problem of the compiler error you mentioned) and instantiated (the problem of NPE even if you just declare field).
As the bottom line I can suggest you to follow ActionScript naming and coding conventions to talk other people and team members about your code :)
I have a doubt,.... How would you create a Singleton class in Flex...
Is there any convention like the class name should eb Singleton or it should extend any other class.
How many Singleton class can a project have?
Can anyone say the real time usage of a Singleton class?
I am planning to keep my components label texts in a Singleton class... Is it a good approach.
Can of worms asking about singletons!
There are a few different options about creating singletons mainly due to AS3 not having private constructors. Here's the pattern we use.
package com.foo.bar {
public class Blah {
private static var instance : Blah;
public function Blah( enforcer : SingletonEnforcer ) {}
public static function getInstance() : Blah {
if (!instance) {
instance = new Blah( new SingletonEnforcer() );
}
return instance;
}
...
}
}
class SingletonEnforcer{}
Note that the SingletonEnforcer class is internal so can only be used by the Blah class (effectively). No-one can directly instantiate the class, they have to go through the getInstance() function.
hope I'm not hitting dead horses here :)
(edit: ahh, I'm just repeating phils link)
Gregors singleton implementation does not protect against invoking the constructor with a null value, as in:
var b:Blah = new Blah(null);
You will still have only 1 instance, but invoking the constructor is still possible with the consequences that follows.
If you absolutely must enforce the singleton, the constructor should make sure that the enforcer parameter isn't null.
public function Blah( enforcer : SingletonEnforcer ) {
if(!enforcer){
throw new Error("whoops!");
}
}
You should also be concerned about ApplicationDomain when loading swf files. External swf files that uses the same definitions, may have multiple singleton instances (1 in each separate applicationdomain) if you do not specify that the swf file must be loaded into the existing applicationdomain.
This means that Blah.getInstance() in AAA.swf is not the same instance as Blah.getinstance() in BBB.swf, if AAA.swf loads BBB.swf without a LoaderContext instance that tells the plugin to load BBB.swf into the same ApplicationDomain as AAA.swf
First you can reference a previous question to find out how to create a singleton class. You can find more info from a Yakov Fain presentation as well.
Second question, your project can technology have as may singleton class as you see fit but it will only create 1 instance of each. For example, in the cairngorm architecture you have 3 main singletons: controller, service and model. The number of actual class can very depending on your project.
Finally, A real world solutions would be. You have 2 components that need to talk to each other but you don't want them to know the other exists. Meaning sometimes the components are there and sometimes they are not...so you need them to be loosely coupled. you can uses singletons to pass the data from one component to the other with out "talking" to them directly.
Using singletons is a good approach if you need to pass data around your application from component to component and would like to decouple them from each other.
package com.foo.bar
{
public class MySingleton
{
private static var _instance:MySingleton = new MySingleton;
private var _myName:String;
public static function get instance():MySingleton
{
return _instance;
}
public function set myName(value:String):void
{
_myName = value;
}
public function get myName():String
{
return _myName;
}
}
}
Notice the absence of a constructor here.
Hello you could check out the following of a Flex Singleton Class example on http://www.how-to-code.com/flex/flex-design-patterns/flex-singleton-class.html
I am using a Cairngorm MVC architecture for my current project.
I have several commands which use the same type of function that returns a value. I would like to have this function in one place, and reuse it, rather than duplicate the code in each command. What is the best way to do this?
Create a static class or static method in one of your Cairngorm classes.
class MyStatic
{
public static function myFunction(value:String):String
{
return "Returning " + value;
}
}
Then where you want to use your function:
import MyStatic;
var str:String = MyStatic.myFunction("test");
Another option is to create a top level function (a la "trace"). Check out this post I wrote here.
You have lots of options here -- publicly defined functions in your model or controller, such as:
var mySharedFunction:Function = function():void
{
trace("foo");
}
... static methods on new or existing classes, etc. Best practice probably depends on what the function needs to do, though. Can you elaborate?
Create an abstract base class for your commands and add your function in the protected scope. If you need to reuse it anywhere else, refactor it into a public static method on a utility class.