Here is how to set a custom mp3 sound when receiving a Message. I wonder why HTC didn’t provide a good interface out of the box.
- Plug your phone to USB selecting USB Disk
- Browse up to /media/audio/notifications
- Copy your mp3 in here and disconnect the phone
- Get into the messages applications
- Select menu->settings and change the notification sound using the provided interface.
Done done.
Last time we see how to use Sling servlets with old legacy URL. Today we’ll see how to create Sling Servlets in the Sling-way: using resourceType.
Scenario
We want a component that can be dragged into a parsys. With a form that submit data to a sling servlet. Then the servlet will do the operations required.
Process
Let’s create the component following the CQ guidelines for making it drag-droppable into a parsys (allowedParents): geometrixx/components/test003. The test003.jsp will look like the following:
<%@include file="/libs/foundation/global.jsp"%>
<form name="frm" method="post" action="<c:out value="${resource.path}" />.c">
<input type="submit" />
</form>
This JSP will answer at a GET http call showing the form. In order to use, create a content page and drag the component into a parsys.
Now it’s time to create the servlet. As usual you’ll have to register it using some felix annotations. The following servlet will be used when posting (HTTP POST) to a resource of type geometrixx/components/test003 with an extension of “c”.
package com.samples.sling;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @scr.component immediate="true" metatype="false"
* @scr.service interface="javax.servlet.Servlet"
* @scr.property name="sling.servlet.methods" values.0="POST"
* @scr.property name="sling.servlet.resourceTypes" values.0="geometrixx/components/test003"
* @scr.property name="sling.servlet.extensions" values.0="c"
*/
public class ResourceTypePostServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = 8795673847499208743L;
private final static Logger logger = LoggerFactory.getLogger(ResourceTypePostServlet.class);
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
logger.debug("ResourceTypePostServlet::doPost()");
response.setContentType("text/plain");
response.getOutputStream().print("Hello ResourceTypePostServlet World!");
}
}
We used the sling.servlet.methods to specify which HTTP method the servlet listen to, the sling.servlet.resourceTypes to specify all the resource types is should listen to and the .extensions if you wish to specify an extension.
Remember that if you specify a sling.servlet.paths, resourceTypes, extensions and selectors will be ignored.
Now build the bundle and refresh the previously created content page (should not necessary actually). If you click on the “submit” button you’ll see the Hello World.
References:
In this short article (first of a serie I hope) I’ll show you how to create a Sling Servlet in CQ.
Scenario
You are migrating your existing application in CQ a piece at time and it’s time for the Servlets (controllers) part, so for the first stage you’d like to keep the old URLs. Maybe because some other external services are calling you at these coordinates or because you don’t want to enter each jsp and change the forms action.
Ingredients
- CQ instance running in Author (localhost:4502)
- CRXDE (let’s ease the game for starting)
Process
Create a new OSGi bundle under geometrixx (or your app). In this create a new class that extends the SlingSafeMethodsServlet.
Then you have to register as a service in the OSGi container. This is done using the Felix annotations as following:
/** * @scr.component immediate="true" metatype="false" * @scr.service interface="javax.servlet.Servlet" * @scr.property name="sling.servlet.methods" values.0="GET" * @scr.property name="sling.servlet.paths" values.0="/path/to/my/servlet" * values.1="/apps/path/to/my/servlet" */
I’ll leave you to the references section of this post for getting deeper into the meaning of each.
At the end your code will look something like the following:
package com.samples.sling;
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @scr.component immediate="true" metatype="false"
* @scr.service interface="javax.servlet.Servlet"
* @scr.property name="sling.servlet.methods" values.0="GET"
* @scr.property name="sling.servlet.paths" values.0="/path/to/my/servlet"
* values.1="/apps/path/to/my/servlet"
*/
public class AbsoluteUrlServlet extends SlingSafeMethodsServlet {
private static final long serialVersionUID = -1920460619265757059L;
private static final Logger logger = LoggerFactory.getLogger(AbsoluteUrlServlet.class);
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
logger.debug("AbsoluteUrlServlet::doGet()");
response.setContentType("text/plain");
response.getOutputStream().print("Hello AbsoluteUrlServlet World!");
}
}
Looking at the sling.servlet.paths annotation we se on which url we are actually mapping the servlet: /path/to/my/servlet and /apps/path/to/my/servlet.
Building the bundle and CRXDE+felix will do the magic of the deployment.
Now if you try to run localhost:4502/apps/path/to/my/servlet you’ll see our beautiful Helloworld, but if you’ll try to access localhost:4502/path/to/my/servlet you’ll get a 404 or a content listing.
This is due to a settings in felix+Sling. Open the felix console at the configuration tab (/system/console/configMgr) and search for Apache Sling Servlet/Script Resolver and Error Handler. Here you’ll have to add “/path/” to the Execution Paths section.
Done done!
References
Here I’ll try to summarize 5 reasons of why Adobe/Day CQ DOESN’T suck; it’s only perceived by the end user in this way.
1. Your organization is not ready for the new paradigm
If you are not ready to change your habits in web applications delivery/development and you’re not going to thinking of the web page in term of content and don’t provide appropriate roles as authors, reviewers and developers… Yes in your case CQ can sucks.
2. You are not willing to learn
If don’t want to learn the full stack of CQ, the way of using it at his maximum potentials and stuck on your position that you still want to deliver “full pages” (JSP) instead of thinking in term of templates and components… Yes in your case CQ can sucks.
3. You don’t want to listen to consultant
Adobe/Day consultant are there to help you in delivering your site as fast as possible and at the best of all your (reasonable) requirements. If you ask them for an opinion/solution and when it’s given, you reply them «…sorry I don’t like it. Don’t you have something else…», always try to impose your mind instead of open-thinking and understanding something new. Yes in your case CQ can sucks.
4. No magic button
There’s no magic button/tool. If you bought CQ because you saw his potentials in leaning the delivery of content for web applications and you wanted to lean your 6 weeks delivering delta for each editing but then you’re not changing your internal procedure and stuck yourself in a 6 week review for each content change… well… Yes in your case CQ sucks.
Corollary: if you want to migrate your existing application and content, there’s no magic button/trick/shortcut. You’ll have to roll-up your sleeves, plan the correct amount of time and budget and start doing the actual job by cutting endless, futile, time-wasting meeting. Again: listen to your Adobe/Day consultants.
5. Wrong tool
You simply bought the wrong tool. CQ is an amazing WCM with DAM and some other cool stuff. If you bought it for implementing your cool ultra-customized-very-integrated-with-internal-corporate-process web application most probably you did the wrong purchase. Having the Sling stack in the middle with OSGI as well, it’s technically possible to do almost everything but this doesn’t mean that it’s sane to do it. Yes in your case CQ can sucks.
Corollary: JEE != OSGI.
The moral of the story is that CQ is a very amazing product, but as all changes in every aspects of life, you have to be ready to take the changes otherwise you’ll end up having another product that at the end you wont like. Sure it has his bugs and way to improve; but do you know of any products that is completely bug-free?
Linkcheker it’s a very useful functionality that highlight to the author eventual broken links within, for example, a RichText widget. However when integrating already existent web application behind apache, there’s the need to “disable” completely it.
We won’t go to disable it properly but configuring it in a way that for him all links are not to be checked.
In CQ5.4, go into the Felix console and click con components (http://<server>:<port>/system/console/components) and search for: com.day.cq.rewriter.linkchecker.impl.LinkCheckerImpl. Click on the wrench (settings) and in the link check override patterns add the following regex (using the “+” button): ^.*$.
Save and refresh the page in the author.
This will save the settings into the file crx-quickstart/launchpad/config/com/day/cq/rewriter/linkchecker/impl/LinkCheckerImpl.config.
If you want to set the config into the CRX repository (so it can be exported/imported via package manager) go to /libs/cq/linkchecker/config/com.day.cq.rewriter.linkchecker.impl.LinkCheckerImpl using Content Explorer and edit the property service.check_override_patterns adding the regex previously mentioned.
Easy peasy!
Here at a customer site, we have a CQ application deployed into “/” context root (as usual) of weblogic 9.2 alongside other functional web apps. All of this sites behind Apache httpd which serves some html files as well as reverse proxies to weblogic based on some urls.
Generally there’s no problem in this except that in this case, when accessing from apache the “/” it serves its htdocs directory so we are not able to login to cq. When logging into CQ, the login form POSTs to http://admin:admin@<server>/?sling:authRequestLogin=1 which needs to be proxied to CQ’s / instead of Apache’s htdocs. As apache is serving its content, no CQ filter is fired.
If we make the weblogic-handler module to come in action for “/” we loose all the apache content. As well, we cannot move all the apache content into CQ.
So the problem is how do we make Apache to use weblogic handler only for a particular URL and query string? We’ve come to a solution combining both Apache configs and some crx node creation.
First, the apache configs:
<LocationMatch "^/(content|libs|siteadmin|apps|bin|home|etc|welcome|var|tmp|cf|useradmin|damadmin|miscadmin|workflow|tagging|inbox|cqauthurl)">
SetHandler weblogic-handler
</LocationMatch>
This sets all the urls in the LocationMatch to be handled by weblogic-handler to proxy to CQ.
As you may have noticed we are dealing with a /cqauthurl that is not a CQ url. We need to use Content Explorer to create the node /cqauthurl (nt:unstructured). This will avoid a 404.
The add the following rewrite rule in Apache configs; as general or within the location should make no difference:
RewriteRule ^/cqlogin$ /libs/cq/core/content/login.html?resource=/siteadmin [R]
RewriteCond %{QUERY_STRING} ^sling:authRequestLogin=1$
RewriteRule (.*) /cqauthurl [PT]
The first line will allow the user to bookmark a simple url like http://<server>/cqlogin. When accessing this url there will be a redirect onto the CQ’s Login.
The second and third lines tells apache: when on the query string there’s sling:authRequestLogin=1 then rewrite to /cqauthurl.
This lets the user’s login go through to CQ and caches the basic auth credentials for all paths under http://author-server:port/
CQ Site admin needs to be accessed via http://author-server:port/siteadmin instead of the root context.
AeroVironment/DARPA Nano Hummingbird UAV flying
Hello JavaFX 2! – A TableView Component
London Stock Exchange in historic Linux go-live
Microsoft: Absolutely NO (GPLv3-or-compat-licensed) Free Software for Windows Phone and Xbox Apps.
BMW Wants to Be the Ultimate Green Machine
Intel’s Light Peak May See the Light This Week.
Intel details Thunderbolt, says Apple has full year head start
Hello JavaFX 2! – Back To Java
Making of JBoss Enterprise Web Server
Applying agile practices in an environment of mistrust
Generate Test Data with DataFactory
The Roadmap for Day Software and LiveCycle ES – a Focus on UX
Springfuse generates Primefaces with Spring Web Flow front end
Spring MVC Development – Quick Tutorial
Open Letter from CEO Stephen Elop, Nokia and CEO Steve Ballmer, Microsoft
No more nokia phones for me.
Hackers penetrated Nasdaq’s network
Using Java 6 processors in Eclipse
Next level of Don’t Repeat Yourself(DRY) principle
Java FX 2.0 – The Installation, Doc and Launch Experience – A Smoke Test
Linux vulnerable to Windows-style autorun exploits and fixed.
Dependency Injection Performance in Java EE 6: Dependent (easy) vs ApplicationScoped (“optimized”)
