Maven plugin complex parameter initialization via system properties - maven-2

I need to run maven plugin from console. In plugin i need a complex parameter kind of:
/**
* #goal do-automation
**/
public class AutomationMojo extends AbstractMojo {
/**
* The current maven project.
*
* #parameter expression="${project}"
*/
protected MavenProject project;
/**
* App configuration.
*
* #parameter expression="${appConfig}"
*/
private AppConfig appConfig;
AppConfig parameter looks smth like this:
public class AppConfig {
private String path
private String version
}
I will be running maven plugin in the following way:
mvn group:artifact:version:do-automation -Dproperty.for.appConfig
How can i set AppConfig properties via system properties? It is possible?
i tried the following and it didn't work for me:
public class AppConfig {
/**
* #parameter expression="${path}"
*/
private String path
private String version
}
mvn group:artifact:1.0-SNAPSHOT:do-automation -DappConfig.path=122 -Dpath=122
It created AppConfig with null values for properties
I am using:
Apache Maven 2.2.1 (r801777; 2009-08-06 14:46:01-0430)
Java version: 1.6.0_21
Java home: c:\Program Files\Java\jdk1.6.0_21\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7" version: "6.1" arch: "x86" Family: "windows"

Actually Maven 3 provides some other means to do what you want. Please, have a look to this link, section (Bean Default Properties)
http://blog.sonatype.com/people/2011/03/configuring-plugin-goals-in-maven-3/
You can define set(String configStr) method in your AppConfig and parse string passed from command line. For Instance.
mvn group:artifact:1.0-SNAPSHOT:do-automation -DappConfig=my/path,version
Then you will be able to parse "my/path,version" in the set(...) method appropriately.

you have read this already. Here is an excerpt:
configuration #parameter expression="${aSystemProperty}"
default-value="${anExpression}"
Specifies the expressions used to calculate the value to be injected
into this parameter of the Mojo at buildtime. The expression given by
default-value is commonly used to refer to specific elements in the
POM, such as ${project.resources}, which refers to the list of
resources meant to accompany the classes in the resulting JAR file. Of
course, the default value need not be an expression but can also be a
simple constant like true or 1.5. And for parameters of type String
one can mix expressions with literal values, e.g.
${project.artifactId}-${project.version}-special. The system property
given by expression enables users to override the default value from
the command line via -DaSystemProperty=value. NOTE: If neither
default-value nor expression are specified, the parameter can only be
configured from the POM. The use of '${' and '}' is required to
delimit actual expressions which may be evaluated.

you should change your configuration like the following:
/**
* App configuration.
*
* #parameter
*/
private AppConfig appConfig;
public class AppConfig {
/**
* #parameter expression="${appConfig.path}"
*/
private String path
/**
* #parameter expression="${appConfig.version}*/
private String version
}
This should give the opportunity to use your system configuration arguments. First i would check if the configuration via usual configuration tag for a plugin works as expected to see if something different is wrong.

Related

Use Proguard 5.3 ,default type methods change to public type

I want to develop a private SDK(a jar file),some method is default permission,i want it can be called in current package only,like this:
/* package */
static String getApplicationId() {
return mApplicationId;
}
but,when use proguard to make jar later,this method change to public type,and the method name like this:
public static String c() {
return sApplicationId;
}
so i want know how to config proguard file.to make default permission method can't visiable when use this jar by proguard later,thanks
You should check your configuration, most likely you have the following setting enabled:
-allowaccessmodification
When obfuscating a library, you normally do not want this enabled, as you experience the effects as described in the question.

TYPO3 extbase: get some from FrontendUserGroupRepository

In a class file I can get all records from another repository that is not mine
$allUsergroups = $this->feGroupRepository->findAll();
How to make custom function to acomplish something like this on such a repository in the most correct way?
// magic default function that takes a uid list (or array) as argument
$someUsergroups = $this->feGroupRepository->findSomeByUidList('2,4,6,8');
Or can I extent an existing repository with my own custom functions, in this case based on $query->in(list)?
You can create your own method in your extensionRepository.php class
you can use :
in($propertyName, $operand)
or
contains($propertyName, $operand)
Contrarily, the methods in() and contains() accept multi-value data types as arguments (e.g. Array, ObjectStorage).
take a look how some other extension are doing stuff. (like the tx_news extension)
or read some docs here :
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/3-implement-individual-database-queries.html
Yes, you can extend another class in TYPO3 without any need to change any other code. It´s called Dependency Injection in ExtBase context.
First, create a new repository class your_ext/Classes/Domain/Repository/FrontendUserRepository.php and add below content to it:
<?php
namespace Tillebeck\YourExt\Domain\Repository;
class FrontendUserRepository extends \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository {
/**
* #param array $uidList
* #return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
*/
public function findByUidList(Array $uidList)
{
$query = $this->createQuery();
//$query->getQuerySettings()->setRespectStoragePage(false);
$query->matching(
$query->in('uid', $uidList)
);
return $query->execute();
}
/**
* #return string
*/
protected function getRepositoryClassName()
{
return get_parent_class($this);
}
}
Here we have implemented your method findByUidList with the required argument $uidList which needs to be an array.
Because repositories resolve their model names by their own class name, we need to change the method getRepositoryClassName to return the parent class name, in this case TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository.
But this alone won't work. We need to tell ExtBase that every time we inject or initialize a TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository, either by PHPDocBlock annotation #inject or by the objectManager->get, then we really want to initialize our new repository. This is done in TypoScript.
config.tx_extbase.objects {
TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository {
className = Tillebeck\YourExt\Domain\Repository\FrontendUserRepository
}
}
You can also restrict your change to your own extension alone by replacing config.tx_extbase with plugin.tx_yourext.
Last step: clear ALL cache, and possibly delete all files in typo3temp directory.
Now in your controller (or other class) you can run below code.
$uidList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', '2,4,6,8', true);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(
$this->frontendUserRepository->findByUidList($uidList)
);
I have tested above solution in TYPO3 7.6 and it works. Dependency Injection has existed since version 6.1.
This is by my definition the must correct way, as you asked, to implement this feature in your own TYPO3 extension.

How to inject a custom (non-bean) value to JAX-RS resources?

With following JAX-RS resource class,
#Path("/myresource")
class MyResource {
#GET
public Response readSomeValue() {
// ...
}
#Inject
private int someValue;
}
How can I inject someValue?
I'm using org.glassfish.jersey.bundles:jaxrs-ri with Spring on Apache Tomcat. No EJBs.
I, so far, found this.
/**
* Is this gonna work?
*/
class SomeValueProducer {
#Produces
public int produceSomeValue() {
/// ...
}
}
Is this the only way? Using #Procudes?
Where can I place the producer class? Just alongside the resource class?
Do I need a beans.xml?
Do I need a qualifier annotation?
Thanks.
Is this the only way? Using #Procudes?
Yes
Where can I place the producer class? Just alongside the resource class?
doesnt matter, every jar with a valid beans.xml should be scanned from the framework if configured correct: including every package in your project.
Do I need a beans.xml?
yes
Do I need a qualifier annotation?
yes, without a qualififer every method which returns an int value is a possible source for an injection.

See inherited documentation in PHPStorm

I usually put the documentation in the interface if I can:
interface SenderInterface
{
/**
* Sends Email to user
*
* #param UserInterface $receiver
* #param string $msg
*/
public function sendEmail(UserInterface $receiver, $msg)
//...
{
I then inherit the doc like this to avoid redundancy.
class Sender implements SenderInterface
{
/**
* {#inheritDoc}
*/
public function sendEmail(UserInterface $receiver, $msg)
//...
{
Is there a way to see the inherited doc directly into the Sender class without having to open the SenderInterface in PHPStorm?
The upcoming PhpStorm v6 has much better support of {#inheritDoc} (in comparison to v5 and earlier).
The functionality you require is already working fine in EAP build (Early Access Program) -- you can try it yourself from here: http://confluence.jetbrains.net/display/WI/Web+IDE+EAP
Command to view documentation is View | Quick Documentation (Ctrl+Q .. or whatever shortcut you may have there)

Can Jython-based Java classes from an Eclipse PyDev project code be referenced by an Eclipse plugin project?

The following explains my attempts at trying to make a hybrid PyDev/Eclipse plugin project. I have since discovered that even if I make a separate PyDev project, I cannot use my PyDev Jython-based Java classes by referencing the project in a plug-in project. On the other hand, I can use the PyDev Java classes in a separate project that is NOT a plugin project.
I've got an eclipse plugin that I've also set as a PyDev project. I built it based on Jython Book v1.0 documentation chapter 10 and chapter 11.
When I run Main as seen below, I see
1 BUIDING-A 100 MAIN ST
When I try to do the same thing within a plug-in project that is set as a PyDev project (right click on project->Pydev->Set as Pydev Project), I get an ImportError: no module named Building. It seems like the plugin nature of the project is trumping the PyDev nature of the project.
Any ideas?
I've put the Main function below followed by some support code.
package org.jython.book;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jython.book.interfaces.BuildingType;
import org.jython.book.util.JythonObjectFactory;
public class Main {
public static void main(String[] args) {
// Obtain an instance of the object factory
JythonObjectFactory factory = JythonObjectFactory.getInstance();
// Call the createObject() method on the object factory by
// passing the Java interface and the name of the Jython module
// in String format. The returning object is casted to the the same
// type as the Java interface and stored into a variable.
BuildingType building = (BuildingType) factory.createObject(
BuildingType.class, "Building");
// Populate the object with values using the setter methods
building.setBuildingName("BUIDING-A");
building.setBuildingAddress("100 MAIN ST.");
building.setBuildingId(1);
System.out.println(building.getBuildingId() + " " + building.getBuildingName() + " " +
building.getBuildingAddress());
}
}
Here is the JythonObjectFactory which should be exactly like what is in [Jython Book v1.0 documentation chapter 10][3], with typos corrected, of course :-)
package mypackage.files.util;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
/**
* Object factory implementation that is defined
* in a generic fashion.
*
*/
public class JythonObjectFactory {
private static JythonObjectFactory instance = null;
private static PyObject pyObject = null;
protected JythonObjectFactory() {
}
/**
* Create a singleton object. Only allow one instance to be created
*/
public static JythonObjectFactory getInstance(){
if(instance == null){
instance = new JythonObjectFactory();
}
return instance;
}
/**
* The createObject() method is responsible for the actual creation of the
* Jython object into Java bytecode.
*/
public static Object createObject(Object interfaceType, String moduleName){
Object javaInt = null;
// Create a PythonInterpreter object and import our Jython module
// to obtain a reference.
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("from " + moduleName + " import " + moduleName);
pyObject = interpreter.get(moduleName);
try {
// Create a new object reference of the Jython module and
// store into PyObject.
PyObject newObj = pyObject.__call__();
// Call __tojava__ method on the new object along with the interface name
// to create the java bytecode
javaInt = newObj.__tojava__(Class.forName(interfaceType.toString().substring(
interfaceType.toString().indexOf(" ")+1,
interfaceType.toString().length())));
} catch (ClassNotFoundException ex) {
Logger.getLogger(JythonObjectFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return javaInt;
}
}
If you have multiple natures added to the project, all builders related to those projects will be invoked by Eclipse. So if the build fails with some PyDev related error message, this really indicates a problem with the PyDev part, not with PDE. Maybe you are missing some additional files or project settings for that project?
Generally speaking, you should avoid mixing multiple natures in one project. This often leads to trouble, because most builders and other extensions expect that they are "the one and only" tinkering with a project. And almost all use cases involving multiple natures can more easily be solved by having two different projects, where one project references the other project (and can then access resources of that referenced project). See Project properties -> Referenced Projects for that.