hi i'm using pretty faces 3.3.3 in tomcat 7
and this config
<rewrite match="/browse" trailingSlash="append" toCase="lowercase" />
<url-mapping id="browsecategory">
<pattern value="/browse/" />
<view-id value="/browser.xhtml" />
</url-mapping>
i want requests without trailing slash after "browse" to be redirected to browse/ (with trailing slash). The background: if the trailing slash is missing, my relative outputLinks are not handeled as subdirectorys, but as files in the current directory.
when i request now
localhost:8081/App/browse
my browser gets into a redirect loop
EDIT:
is it possible that browse is a reserved keyword? when i replace it with squirrel everything works as expected:
<rewrite match="/squirrel" trailingSlash="append" toCase="lowercase" />
<url-mapping id="browsecategory">
<pattern value="/squirrel/" />
<view-id value="/browser.xhtml" />
</url-mapping>
Because of the amount of confusion that has occurred using the <rewrite/> tag in PrettyFaces, we've migrated to a new core architecture for PrettyFaces (//Rewrite 2.0.0.Final) that provides much greater control over application configuration. (Available here http://ocpsoft.org/prettyfaces/)
I would recommend trying PrettyFaces 4 if your environment permits. You can leave your URL-mappings in the pretty-config.xml file if you wish, but you can now define more custom Rewrite rules, more safely, in a Rewrite ConfigurationProvider:
<!-- for JSF 2.x -->
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-servlet</artifactId>
<version>2.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-config-prettyfaces</artifactId>
<version>2.0.0.Final</version>
</dependency>
Leave your pretty-config.xml as it is:
<url-mapping id="browsecategory">
<pattern value="/browse/" />
<view-id value="/browser.xhtml" />
</url-mapping>
Now also create a ConfigurationProvider to handle your trailing slashes:
public class RewriteConfig extends HttpConfigurationProvider
{
#Override
public int priority()
{
return 10;
}
#Override
public Configuration getConfiguration(final ServletContext context)
{
return ConfigurationBuilder.begin()
.addRule()
.when(Direction.isInbound().and(Path.matches("/{p}")))
.perform(Redirect.to(context.getContextRoot() + "/{p}/"))
.where("p").matches("^.*[^/]$");
}
}
Don't forget to register/activate the ConfigurationProvider.
Additionally, you can do your URL-mappings in this configuration file as well, thus removing the need for pretty-config.xml or the PrettyFaces 4 con:
public class RewriteConfig extends HttpConfigurationProvider
{
#Override
public int priority()
{
return 10;
}
#Override
public Configuration getConfiguration(final ServletContext context)
{
return ConfigurationBuilder.begin()
.addRule(Join.path("/browse/").to("/browser.xhtml"))
.addRule()
.when(Direction.isInbound().and(Path.matches("/{p}")))
.perform(Redirect.to(context.getContextRoot() + "/{p}/"))
.where("p").matches("^.*[^/]$");
}
}
I didn't test the regular expression in the matches() clause, but it should be something like that. I hope this helps!
The problem is that your trailingSlash rewrite rule also matches things like /browse. Could you try to adjust it like this:
<rewrite match="^/browse$" trailingSlash="append" toCase="lowercase" />
I think this should work, because the rule will now only match exactly /browse and not /browse/.
Related
I hope that you're all coding well. So... I was refactoring the client side of the GWT app I work on and I was wondering about something. Looking after an answer days after days, I decided to ask you for your point of view...
The title is quite understanding, but, there is a snippet of what I'd like to do.
I'd like to change stuff like this
public AnnotatedObject annotated = GWT.create(AnnotatedObject.class);
by something like this
#CreativeAnnotation
public AnnotatedObject;
I had to say that in my xxx.gwt.xml, I have done something like this :
<replace-with class="package.AnnotationObject2">
<when-type-is class="package.AnnotationObject" />
</replace-with>
As you can see, my deffered replacement class is AnnotationObject2, and for the moment, I add a line between the ones above and I have :
<replace-with class="package.AnnotationObject1">
<when-type-is class="package.AnnotationObject" />
<when-property-is name="type" value="object1" />
</replace-with>
<replace-with class="package.AnnotationObject2">
<when-type-is class="package.AnnotationObject" />
<when-property-is name="type" value="object2" />
</replace-with>
I don't really like to play with metadata of my xxx.html, so the result I'd like is this one :
#CreativeAnnotation(type = "object2")
public AnnotatedObject;
So, do you think that sort of thing is possible with GWT (I have to say that I work with GWT 2.5, 'cause of my client desires) ? If yes, may you help me ?
Thanks in advance.
EDIT : I mean, I know about GIN... Just wondering how to do it from scratch.
You can achieve this by using dependency injection with GIN.
GIN automatically use GWT.create() to create an object that has to be injected.
Ex:
class MyView {
interface MyUiBinder extends UiBinder<Widget, MyView> {
}
#Inject
MyView(MyUiBinder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
}
}
And with dependency injection, you also specify which implementation of your interface to instantiate in your GIN module:
public class MyModule extends AbstractGinModule {
protected void configure() {
bind(AnnotationObject.class).annotatedWith(Names.named("object1").to(AnnotationObject1.class);
bind(AnnotationObject.class).annotatedWith(Names.named("object2").to(AnnotationObject2.class);
}
}
And then in your code:
public class MyClass {
#Inject
public MyClass(#Named("object1") AnnotationObject annotationObject) {
...
}
}
You can also use custom binding annotation instead of the Named annotation.
You can write your own generator if you don't want to use GIN - for something like this it would be pretty trivial.
I am trying to implement validation in Eclipse. My work has many little projects that serve to customize our product for various customers. Since there are a ton of developers we are trying to find a way to enforce various standards and best practices.
For example, we have many XML configurations that we want to validate. The built-in validators ensure files are well-formed and follow a schema, but we would like to add validations such as checking that a Java class referenced in XML actually exists on the classpath. Another example is validating that a Java class implementing a certain interface does not have any object variables (i.e. the code needs to operate only on parameters and not maintain state).
It appears that there are two ways to add validation. The first is through a builder which adds markers. The second is through stand-alone validation. However, we are not actually building anything, and I have not found any useful tutorials or examples on validation (does not help that help.eclipse.org is currently being moved and is unavailable).
When I right-click a test project and select "validate" I get a message stating there was an error during validation, and my test message does not show up in the problem view. However, there are no errors in the Eclipse log. The host Eclipse shows nothing in the console. No exceptions logged anywhere, and no message. The project does have the required custom nature.
I was following these instructions but there is no code or fully functioning example, and Google has not been kind enough to fill in the blanks. Combined with the Eclipse help site being down right now, I am at a loss as to how to proceed.
plugin.xml:
<plugin>
<extension name="My Validator" point="org.eclipse.wst.validation.validator"
id="com.mycompany.pluginname.validator.MyValidator">
<validator>
<projectNature id="com.mycompany.pluginname.nature.MyNature"/>
<helper class="org.eclipse.wst.validation.internal.operations.WorkbenchContext"/>
<markerId markerIdValue="com.mycompany.pluginname.validator.DefaultMarker"/>
<run class="com.mycompany.pluginname.validation.validator.MyValidator"/>
<runStrategy project="true"/>
</validator>
</extension>
<extension point="org.eclipse.core.resources.markers" name="My Validator"
id="com.mycompany.pluginname.validator.DefaultMarker">
<super type="org.eclipse.core.resources.problemmarker"/>
<persistent value="true"/>
<attribute name="owner"/>
<attribute name="validationSeverity"/>
<attribute name="targetObject"/>
<attribute name="groupName"/>
<attribute name="messageId"/>
</extension>
</plugin>
Validator code:
package com.mycompany.pluginname.validation.validator;
import org.eclipse.core.resources.IProject;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.provisional.core.*;
import com.mycompany.pluginname.validation.plugin.ValidationPlugin;
#SuppressWarnings("restriction")
public class MyValidator
implements IValidator {
#Override
public void cleanup(IReporter argReporter) {
argReporter.removeAllMessages(this);
}
#Override
public void validate(IValidationContext argContext, IReporter argReporter)
throws ValidationException {
String bundle = ValidationPlugin.getDefault().getTranslationsBundleName();
IProject prj = ((IWorkbenchContext) argContext).getProject();
String[] attributes =
new String[] {"owner", "validationSeverity", "targetObject", "groupName", "messageId"};
IMessage msg = new Message(bundle, IMessage.HIGH_SEVERITY, "test", attributes, prj);
argReporter.addMessage(this, msg);
}
}
I also find it odd that adding validation would require using restricted packages and interfaces. It also seems odd that it wants an IMessage rather than an IMarker.
I did look at Eclipse plugin with custom validation which seems to be oriented around creating a new editor, where I want to validate files regardless of the editor used (in fact I do not want to create an editor).
Edit: I updated to use the V2 framework, but nothing appears in the problem view. What am I doing wrong? Is there a tutorial somewhere that explains how this works? I was able to figure out the following, but obviously it is not correct:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf("bad_string");
if (offset >= 0) {
result.add(ValidatorMessage.create("Found bad string", resource));
result.incrementError(1);
}
}
}
catch (Exception ex) {
result.add(ValidatorMessage.create(ex.getMessage(), resource));
}
return result;
}
I admit this is a stab in the dark: the documentation is not very descriptive and I have not found any tutorials on this V2 validator. Oh, I have a filter on this validator so it only receives specific XML files, which is why there is no input validation.
Also, since I am a pedant myself, I am using the old-style for loop there because I expect to show the line number with the error to the user. But obviously I am not quite there yet.
Another edit: here is the working code. The only issue is the squiggly is not on the correct line because the offset is from the start of the file, not the line. But it does work:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
int location = 0;
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf(CONSTANT);
if (offset >= 0) {
ValidatorMessage vm = ValidatorMessage.create("Message", resource);
vm.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
vm.setAttribute(IMarker.SOURCE_ID, IMarker.PROBLEM);
vm.setAttribute(IMarker.LINE_NUMBER, i + 1);
vm.setAttribute(IMarker.CHAR_START, location + offset);
vm.setAttribute(IMarker.CHAR_END, location + offset + CONSTANT.length());
result.add(vm);
}
// TODO: account for different line endings.
location += (line.length() + 2);
}
}
catch (Exception ex) {
ValidationPlugin.getDefault().warn(ex);
result.add(ValidatorMessage.create(ex.toString(), resource));
}
return result;
}
Plugin.xml:
<extension name="My Validator" point="org.eclipse.wst.validation.validatorV2"
id="com.company.plugin.validation.validator.MyValidator">
<validator class="com.company.plugin.validation.validator.MyValidator">
<include>
<rules>
<file type="file" name="FileName.xml"/>
</rules>
</include>
</validator>
</extension>
I actually found another SO question along these lines that corroborates what I found: Setting IMarker.CHAR_START and IMarker.CHAR_END attributes for IMarkers Annotations
sigh that document is very out of date. You should use the org.eclipse.wst.validation.validatorV2 extension point, extending the newer org.eclipse.wst.validation.AbstractValidator class.
I am using a X.jar and adding to my AspectJ project(in eclipse). I have written pointcut and advice for a method myMethod() inside X.jar.
But aspectj is not intercepting this method call.
How can I tell aspectj to intercept method calls on external jars.Or is it not possible?
Thanks
There are two options:
a) compile the aspects into the JAR
b) use load time weaving (I'd go with that one)
Both of these are advanced topics, I'd suggest you read AspectJ in Action (2nd Ed) by Ramnivas Laddad to learn more.
To clarify: there are different types of pointcuts. If your code calls the library's methods, you can of course intercept these calls, as they happen in your code. So call() pointcuts will work, but execute() (and many other) pointcuts won't because they change the executing method, which is not in your code base. So you have to either change the byte code of the library (option a) or change how it is loaded into your application (option b).
Here is a simple example with AspectJ Load-Time Weaving on GitHub https://github.com/medvedev1088/aspectj-ltw-example
It uses Joda Time library to demonstrate how to intercept the DateTime#toString() method invocations.
The aspect:
#Aspect
public class DateTimeToStringAspect {
public static final String TO_STRING_RESULT = "test";
#Pointcut("execution(* org.joda.time.base.AbstractDateTime.toString())")
public void dateTimeToString() {
}
#Around("dateTimeToString()")
public Object toLowerCase(ProceedingJoinPoint joinPoint) throws Throwable {
Object ignoredToStringResult = joinPoint.proceed();
System.out.println("DateTime#toString() has been invoked: " + ignoredToStringResult);
return TO_STRING_RESULT;
}
}
aop.xml
<aspectj>
<aspects>
<!-- Aspects -->
<aspect name="com.example.aspectj.DateTimeToStringAspect"/>
</aspects>
<weaver options="-verbose -showWeaveInfo">
<include within="org.joda.time.base.AbstractDateTime"/>
</weaver>
</aspectj>
test:
public class DateTimeToStringAspectTest {
#Test
public void testDateTimeToString() throws Exception {
assertThat(new DateTime().toString(), is(DateTimeToStringAspect.TO_STRING_RESULT));
}
}
Surefire plugin configuration from pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<argLine>-XX:-UseSplitVerifier</argLine>
<argLine>-javaagent:${user.home}/.m2/repository/org/aspectj/aspectjweaver/${aspectjweaver.version}/aspectjweaver-${aspectjweaver.version}.jar</argLine>
</configuration>
</plugin>
I would like to have an option wherein a user can choose his theme for the site from the dropdown list and the theme applies to that page [atleast].
I want this to be done in ASP.NET MVC 2 without using jquery like frameworks.
How can this be accomplished.
I am using the default webforms viewengine and donot want to go for a custom viewengine for this purpose.
It seems this is not supported out of the box, but here's what I did to implement theming:
First, I Added the App_Themes folder to my project, and set up a couple of themes
I then decided to try and mimic the Web-forms profile provider as close as possible, and added a profile-property to web.config:
<profile>
<properties>
<add name="ThemePreference" type="string" defaultValue="Blue" />
</properties>
</profile>
So, basically what I wanted to do was to be able to load the different css's from the appropriate theme-folder when the theme changed. I did this by implementing a helper method attached to the UrlHelper class so that I could write:
<link href="#Url.Theme("~/Content/Site.css")" rel="stylesheet" type="text/css" />
This should then load the appropriate themed Site.css, and fall back to ~/Content/Site.css if no file was found.
The helper is pretty simple:
public static class UrlHelpers
{
public static string Theme(this UrlHelper url, string u)
{
if (u.StartsWith("~")) u = u.TrimStart('~');
SettingsProperty settingsProperty = ProfileBase.Properties["ThemePreference"];
return url.Content("~/App_Themes/"+settingsProperty.DefaultValue + u);
}
}
Now, in this version of the code it simply gets the default-value, so you'll need to tweak the code slightly. But as you can see, this is not limited to css-files, but works with everything from .master files to images.
Update - Using Session instead of profile
public static class UrlHelpers
{
public static string Theme(this UrlHelper url, string u)
{
if (u.StartsWith("~")) u = u.TrimStart('~');
object currentThemeName = null;
if (url.RequestContext.HttpContext.Session != null)
{
currentThemeName = url.RequestContext.HttpContext.Session["ThemePreference"];
}
return currentThemeName != null ? url.Content(String.Format("~/App_Themes/{0}{1}", currentThemeName, u)) : url.Content("~"+u);
}
}
The return-line in this method checks if it found a ThemePreference session-value, and then returnes the appropriate URL for the content requested, otherwise it simply returns the content as it was requested with no App_Theme prefix.
In your controlleraction for the DropDown postmethod, you'd simply do:
Session.Add("ThemePreference", whateverValueYouGotFromDropdown);
Update ends
With some tweaking and fixing, this should do the trick.
Hope it helps some, even though it's not a complete walkthrough :)
I have been trying to use the configurable provider model for handling my MEF imports and exports from MEF Contrib (link). I've read the Codeplex documentation and Code Junkie's blog post (link); however, I can't seem to get the container to create the parts. Where am I going wrong?
Program.cs
namespace MEFTest
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
// [ImportMany("command", typeof(IHelp))]
public IEnumerable<IHelp> Commands { get; set; }
void Run()
{
Compose();
foreach(IHelp cmd in Commands)
{
Console.WriteLine(cmd.HelpText);
}
Console.ReadKey();
}
void Compose()
{
var provider = new ConfigurableDefinitionProvider("mef.configuration");
var catalog = new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
TestCommand.cs
namespace MEFTest
{
//[Export("command", typeof(IHelp))]
public class TestCommand : IHelp
{
private string _helpText = "This is a test.";
public string CommandName
{
get { return "Test"; }
}
public string HelpText
{
get { return _helpText; }
}
}
}
App.Config section:
<mef.configuration>
<parts>
<part type="MEFTest.TestCommand, MEFTest">
<exports>
<export contract="IHelp" />
</exports>
</part>
<part type="MEFTest.Program, MEFTest">
<imports>
<import member="Commands" contract="IHelp" />
</imports>
</part>
</parts>
</mef.configuration>
I don't get any build errors and it runs fine if I switch to the typical attribute-based system that is part of the MEF core (with the appropriate catalog too). Program.Commands is always NULL in the above example. I tried to just use a singular property instead of a collection and get the same results.
When I debug I can get the provider.Parts collection so I know it's accessing the configuration information correctly; however, I get an InvalidOperationException whenever I debug and try to drill into catalog.Parts.
Anyone have any experience as to where I'm going wrong here?
As documented here, you also need this in your config file:
<configSections>
<section
name="mef.configuration"
type="MefContrib.Models.Provider.Definitions.Configurable.PartCatalogConfigurationSection, MefContrib.Models.Provider" />
</configSections>
If you already have that, then it might be interesting to show us the stack trace of the InvalidOperationException that you get when accessing provider.Parts.
I had the same problems and could not get it to work, but here are some details:
It seems that ComposeParts() does not work as expected (at least in the version I used) because it uses static methods, based on Reflection to find all required Imports (so it seems that this part cannot be changed from outside of MEF). Unfortunately we want to use xml configuration and not the MEF attributes.
It works if you add [Import] attributes to the members of the class you you use with ComposeParts(). In your case this would be "Programm". In this case all exports defined in the configuration file will be found.
I could not find any documentation or examples on the MEF Contrib page relating to that problem. Also there is no unittest in the MEF contrib projekt that uses ComposeParts().
A workaround would be to use container.GetExportedValues() to retrieve the values, but in this case you have to set the classes members manually.
Hope that helps.