Thymeleaf - manually processing a template and internationalization? - thymeleaf

I am able to process a template manually (without Spring Boot), pass in variables and then output the results to PDF using a Thymeleaf template. However, the messages (text) do not get translated and there seems to be little out there on approaching this.
Here is my current code:
ByteOutputStream os = new ByteOutputStream();
ITextRenderer renderer = new ITextRenderer();
Random rand = new Random();
Integer positiveRandInt = rand.nextInt(Integer.MAX_VALUE) + 1;
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
StandardMessageResolver messageResolver = new StandardMessageResolver();
messageResolver.getDefaultMessages();
TenantDTO tenantDTO = operatorService.getOperatorInfo(saleService.getOperatorId(TenantContext.getCurrentTenant()));
DisplayTransactionDetailsDTO receipt = saleService.getsReceiptForPassenger(transactionNumber);
ReceiptConfig receiptProperties = operatorService.getOperatorProperty();
Operator operator = operatorService.getOperatorAddress();
templateResolver.setPrefix("templates/PDF_Receipt_Template/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
templateEngine.setMessageResolver(messageResolver);
Context ctx = new Context();
ctx.setVariable("locale", locale);
ctx.setVariable("lang", "en");
ctx.setVariable("receipt", receipt);
ctx.setVariable("receiptItems", receipt.getSalesTransactionItems());
ctx.setVariable("receiptPayments", receipt.getSalesTransactionPayments());
ctx.setVariable("receiptPromos", receipt.getSalesTransactionPromos());
ctx.setVariable("receiptTaxes", receipt.getSalesTransactionTaxSummaries());
ctx.setVariable("tenant", tenantDTO);
ctx.setVariable("operator", operator);
ctx.setVariable("receiptProperties", receiptProperties);
String htmlContent = templateEngine.process("pdf_template", ctx);
renderer.setDocumentFromString(htmlContent);
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
byte[] pdfAsBytes = os.getBytes();
os.close();
FileOutputStream fos = new FileOutputStream(new File(positiveRandInt.toString() + "_receipt.pdf"));
fos.write(pdfAsBytes);
fos.close();
Is there a way to access Spring Boots messages (Resource Bundle) without Spring? By specifying the location, or resource from TemplateEngine? Then the proper values would be loaded from, say:
messages.properties
messages_en.properties
messages_fr.properties

MessageSourceResourceBundle.getBundle from org.springframework.context.support
Gets a resource bundle using the specified base name and locale, and the caller's class loader.
#param baseName - the base name of the resource bundle, a fully qualified class name
#param locale - the locale for which a resource bundle is desired
#return a resource bundle for the given base name and locale
public static final ResourceBundle getBundle(String baseName,
Locale locale)

Related

Apache Camel: How to rebuild the url based on the old one or the header

I am using route on the camel that starts a server that is used as an access point to request, re-directions, gateway to database, etc.
And I want to redirect a get request to another service that is in another server and compose the url based on the request. I have made a processor that gets the header and puts in the new url. However the new url does not get executed...
Here is the code:
CamelContext context = new DefaultCamelContext();
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory("vm://localhost?create=false");
context.addComponent("activemq", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.start();
Processor Redir = new RedirectProcess();
from("jetty:http://localhost:8080/Middleware")
.choice()
.when(header("redir")).process(Redir)
.end()
And the Processor
public class RedirectProcess implements Processor {
String value = null;
String Head;
public void process(Exchange inExchange) throws Exception {
Head = inExchange.getIn().getHeader("redir").toString();
CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(route());
camelContext.start();
ProducerTemplate template = camelContext.createProducerTemplate();
template.sendBody("direct:start", "Hello Camel");
System.out.println(Head);
}
public RouteBuilder route() {
return new RouteBuilder() {
public void configure() {
// you can configure the route rule with Java DSL here
System.out.println("Passed HERE!");
from("direct:start")
.to("http://localhost:8081/FunctLayer/tool/start/tool/" + Head + "");
}
};
}
}
It does not work like this. Don't try to create contexts nor routes in runtime. Use Recipient List pattern (http://camel.apache.org/recipient-list.html).
Your code would look like:
CamelContext context = new DefaultCamelContext();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false");
context.addComponent("activemq",JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.start();
from("jetty:http://localhost:8080/Middleware")
.choice()
.when(header("redir"))
.recipientList(simple("http://localhost:8081/FunctLayer/tool/start/tool/${header.redir}"))
.end()

save form values through script file in umbraco

hello i want to save the value of umbraco form in database for this i have made script file and in this script file i have created function to save data and called this function in same script file and this script file is used in macro and i have called this macro in template of my page but it is not working will this approach is proper or i have to something else my basic aim is to save data in database without creating my usercontrol
code is
#functions
{
public void AddToCart()
{
string con = System.Configuration.ConfigurationManager.AppSettings["umbracoDbDSN"].ToString();
SqlConnection OnCon = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["umbracoDbDSN"].ToString());
ItemsDataContext db = new ItemsDataContext(con);
var request = HttpContext.Current.Request;
string itemcode= request.Form["ItemCode"].ToString();
string itemname = request.Form["ItemName"].ToString();
string itemcategory = Request.Form["ItemCategory"].ToString();
string userid = "Pallavi";
db.sp_AddItems(userid, itemcode, itemcategory, itemname, 0);
HttpContext.Current.Session["UserId"] = "Pallavi";
}
}
#if (!IsPost)
{
AddToCart();
}
and called this macro on template
<umbraco:Macro Alias="Uc_Cart" runat="server"></umbraco:Macro>
You approach is wrong. You must use the methods that Umbraco provides in their API and do not try to write data into the database directly.
Try this code to create an new document from Razor code:
#using umbraco.BusinessLogic;
#using umbraco.cms.businesslogic.web;
#{
DocumentType dt = DocumentType.GetByAlias("Textpage");
User author = umbraco.BusinessLogic.User.GetUser(0);
Document doc = Document.MakeNew("My new document", dt, author, parentID);
}
The example above is for Umbraco 4.x. If you're using Umbraco v6.x you could also use the new API methods:
#{
// get an instance of the contentService
var contentService = ApplicationContext.Services.ContentService;
// create new content, the last param is the userId and is optional [default = 0]
IContent newContent = contentService.CreateContent("My new document", parentID, "Textpage", 0);
// set property values
newContent.SetValue("propertyAlias", "Value");
// save (or save and publish)
contentService.Save(newContent);
}

Getting Data from a Website using MVC 4 Web API

This is a follow-up to this post: New at MVC 4 Web API Confused about HTTPRequestMessage
Here is a summary of what I am trying to do: There is a web site that I want to interface with via MVC 4 Web API. At the site, users can log in with a user name and password, then go to a link called ‘Raw Data’ to query data from the site.
On the ‘Raw Data’ page, there is a dropdown list for ‘Device’, a text box for ‘From’ date, and a text box for ‘To’ date. Given these three parameters, the user can click the ‘Get Data’ button, and return a table of data to the page. What I have to do, is host a service on Azure that will programmatically provide values for these three parameters to the site, and return a CSV file from the site to Azure storage.
The company that hosts the site has provided documentation to programmatically interface with the site to retrieve this raw data. The document describes how requests are to be made against their cloud service. Requests must be authenticated using a custom HTTP authentication scheme. Here is how the authentication scheme works:
Calculate an MD5 hash from the user password.
Append the request line to the end of the value from step one.
Append the date header to the end of the value in step two.
Append the message body (if any) to the end of the value in step 3.
Calculate MD5 hash over the resulting value from step 4.
Append the value from step 5 to the user email using the “:” character as a delimiter.
Calculate Base64 over the value from step 6.
The code that I am going to list was done in Visual Studio 2012, C#, .NET Framework 4.5. All of the code in this post is in my 'FileDownloadController.cs' Controller class. The ‘getMd5Hash’ function takes a string, and returns an MD5 hash:
//Create MD5 Hash: Hash an input string and return the hash as a 32 character hexadecimal string.
static string getMd5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
This function takes a string, and returns BASE64:
//Convert to Base64
static string EncodeTo64(string input)
{
byte[] str1Byte = System.Text.Encoding.ASCII.GetBytes(input);
String plaintext = Convert.ToBase64String(str1Byte);
return plaintext;
}
The next function creates an HTTPClient, makes an HTTPRequestMessage, and returns the authorization. Note: The following is the URI that was returned from Fiddler when data was returned from the ‘Raw Data’ page: GET /rawdata/exportRawDataFromAPI/?devid=3188&fromDate=01-24-2013&toDate=01-25-2013 HTTP/1.1
Let me first walk through what is happening with this function:
The ‘WebSiteAuthorization’ function takes a ‘deviceID’, a ‘fromDate’, a ‘toDate’ and a ‘password’.
Next, I have three variables declared. I’m not clear on whether or not I need a ‘message body’, but I have a generic version of this set up. The other two variables hold the beginning and end of the URI.
I have a variable named ‘dateHeader’, which holds the data header.
Next, I attempt to create an HTTPClient, assign the URI with parameters to it, and then assign ‘application/json’ as the media type. I’m still not very clear on how this should be structured.
In the next step, the authorization is created, per the requirements of the API documentation, and then the result is returned.
public static string WebSiteAuthorization(Int32 deviceid, string fromDate, string toDate, string email, string password)
{
var messagebody = "messagebody"; // TODO: ??????????? Message body
var uriAddress = "GET/rawdata/exportRawDataFromAPI/?devid=";
var uriAddressSuffix = "HTTP/1.1";
//create a date header
DateTime dateHeader = DateTime.Today;
dateHeader.ToUniversalTime();
//create the HttpClient, and its BaseAddress
HttpClient ServiceHttpClient = new HttpClient();
ServiceHttpClient.BaseAddress = new Uri(uriAddress + deviceid.ToString() + " fromDate" + fromDate.ToString() + " toDate" + toDate.ToString() + uriAddressSuffix);
ServiceHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//create the authorization string
string authorizationString = getMd5Hash(password);
authorizationString = authorizationString + ServiceHttpClient + dateHeader + messagebody;
authorizationString = email + getMd5Hash(authorizationString);
authorizationString = EncodeTo64(authorizationString);
return authorizationString;
}
I haven’t tested this on Azure yet. I haven't completed the code that gets the file. One thing I know I need to do is to determine the correct way to create an HttpRequestMessage and use HttpClient to send it. In the documentation that I've read, and the examples that I've looked at, the following code fragments appear to be possible approaches to this:
Var serverAddress = http://my.website.com/;
//Create the http client, and give it the ‘serverAddress’:
Using(var httpClient = new HttpClient()
{BaseAddress = new Uri(serverAddress)))
Var requestMessage = new HttpRequestMessage();
Var objectcontent = requestMessage.CreateContent(base64Message, MediaTypeHeaderValue.Parse (“application/json”)
or----
var formatters = new MediaTypeFormatter[] { new jsonMediaTypeFormatter() };
HttpRequestMessage<string> request = new HttpRequestMessage<string>
("something", HttpMethod.Post, new Uri("http://my.website.com/"), formatters);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpClient = new HttpClient();
var response = httpClient.SendAsync(request);
or------
Client = new HttpClient();
var request = new HttpRequestMessage
{
RequestUri = "http://my.website.com/",
Method = HttpMethod.Post,
Content = new StringContent("ur message")
};
I'm not sure which approach to take with this part of the code.
Thank you for your help.
Read this step by step tutorial to understand the basic.

Localization in MonoDroid

My app is localized using the standard .NET RESX methods (ie. String.fr.resx, Strings.de.resx etc.) works great under Windows Phone.
I am porting to Android using MonoDroid and I do not see the localized UI when I switch locales on the phone. If I rename the APK file to ZIP and open it I see that it has not packaged up the locale DLLs produced during the build (ie. the intermediate \.Resources.dll files are under the bin directory but are not packaged into the APK).
What am I missing? I have tried changing the build action on the RESX files from "Embedded Resource" to "Android Resource" and even "Android Asset" but to no avail.
Thanks in advance for any help!
Cheers
Warren
I asked about this on the monodroid irc channel and the official answer was "not supported yet but we do have plans to do it".
You need to convert the resx files to android xml format (see below) and add them to your project as shown here: http://docs.xamarin.com/android/tutorials/Android_Resources/Part_5_-_Application_Localization_and_String_Resources
In my app (game) I needed to look up the localised strings by name. The code to do this was simple but not immediately obvious. Instead of using ResourceManager I swapped in this for android:
class AndroidResourcesProxy : Arands.Core.IResourcesProxy
{
Context _context;
public AndroidResourcesProxy(Context context)
{
_context = context;
}
public string GetString(string key)
{
int resId = _context.Resources.GetIdentifier(key, "string", _context.PackageName);
return _context.Resources.GetString(resId);
}
}
Since I'm not a XSLT guru I made a command line program for converting resx to Android string XML files:
/// <summary>
/// Conerts localisation resx string files into the android xml format
/// </summary>
class Program
{
static void Main(string[] args)
{
string inFile = args[0];
XmlDocument inDoc = new XmlDocument();
using (XmlTextReader reader = new XmlTextReader(inFile))
{
inDoc.Load(reader);
}
string outFile = Path.Combine(Path.GetDirectoryName(inFile), Path.GetFileNameWithoutExtension(inFile)) + ".xml";
XmlDocument outDoc = new XmlDocument();
outDoc.AppendChild(outDoc.CreateXmlDeclaration("1.0", "utf-8", null));
XmlElement resElem = outDoc.CreateElement("resources");
outDoc.AppendChild(resElem);
XmlNodeList stringNodes = inDoc.SelectNodes("root/data");
foreach (XmlNode n in stringNodes)
{
string key = n.Attributes["name"].Value;
string val = n.SelectSingleNode("value").InnerText;
XmlElement stringElem = outDoc.CreateElement("string");
XmlAttribute nameAttrib = outDoc.CreateAttribute("name");
nameAttrib.Value = key;
stringElem.Attributes.Append(nameAttrib);
stringElem.InnerText = val;
resElem.AppendChild(stringElem);
}
XmlWriterSettings xws = new XmlWriterSettings();
xws.Encoding = Encoding.UTF8;
xws.Indent = true;
xws.NewLineChars = "\n";
using (StreamWriter sr = new StreamWriter(outFile))
{
using (XmlWriter writer = XmlWriter.Create(sr, xws))
{
outDoc.Save(writer);
}
}
}
}

Relative path on File.ReadAllLines method

My code access a file which is in "Conf" directory inside my project directory. I am currently opening the file using absolute path like below:
File.ReadAllLines("C:\project name\Conf\filename");
I was thinikng if it's possible to use the relative path like
File.ReadAllLines("/Conf/filename");
But it's not working; as expected it throws exception. I did checked MSDN (link below) but seems "ReadAllLines()" methods doesn't accept relative path.
http://msdn.microsoft.com/en-us/library/s2tte0y1.aspx
Any idea, how can I use the relative path instead using absolute path?
Thanks,
Rahul
This is my favorite way of doing it.
Make your file an embedded resource.
/// <summary>
/// This class must be in the same folder as the embedded resource
/// </summary>
public class GetResources
{
private static readonly Type _type = typeof(GetResources);
public static string Get(string fileName)
{
using (var stream =
_type.Assembly.GetManifestResourceStream
(_type.Namespace + "." + fileName))
{
if (stream != null)
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
throw new FileNotFoundException(fileName);
}
}
As stated in MSDN you cannot use a relative path, however you might be able to use either Environment.CurrentDirectory or System.Reflection.Assembly.GetExecutingAssembly().Location
To make things simple, use the following:
string current_path = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
string[] lines_from_file = System.IO.File.ReadAllLines(current_path + "/Conf/filename");
...additional black magic here...

Resources