I'm trying to parse an URL in order to obtain the current branch or trunk.
public SVNConnector(String s_Url, String login, String password, String project) {
try {
url = SVNURL.parseURIEncoded(s_Url);
ISVNAuthenticationManager authManager = new BasicAuthenticationManager(login, password);
DAVRepositoryFactory.setup();
repository = SVNRepositoryFactory.create(url, null);
repository.setAuthenticationManager(authManager);
this.projectName = project;
latestRevision = repository.getLatestRevision();
} catch (SVNException svne) {
logger.error("Impossible to connect to SVN repository. s_Url: "+s_Url+" login:"+login+" password: "+password, svne);
}
}
My URL is something like http://10.61.128.222/svn/i18ntest/trunk or http://10.61.128.222/svn/PFT/branches/protoi18n and I need a method where I could enter this URL and it would return /trunk/ or /branches/protoi18n/, so I could run this:
public List<OutputElement> retrieveI18nFiles() throws SVNException {
List<OutputElement> outs = new ArrayList<OutputElement>();
String path = url.getPath()+"/core/src/main/resources/fr/gefco/"+projectName+"/i18n/"; // this is not working!
latestRevision = repository.getLatestRevision();
// For some reason, type safety is not insured in SVNKit, even if generics are around for some years, now
Collection<SVNDirEntry> entries = repository.getDir(path, latestRevision, (SVNProperties)null, (Collection<SVNDirEntry>)null);
for (SVNDirEntry entry : entries) {
OutputElement out = new OutputElement();
out.setEntry(entry);
out.setOut(retrieveOutputStream(entry,path));
outs.add(out);
}
return outs;
}
url.getPath() is returning /svn/i18ntest/trunk/, which is not what I need. Of course, I could parse it to get the bit I need, but I would like to know first if SVNKit provides any already proven way to do that.
When working with SVNRepository you need paths relative to the repository root. You may retrieve the repository root URL using SVNURL root = repository.getRepositoryRoot(true) and then use SVNURLUtil.getRelativeURL(root, url, false) to get the relative path between your url and the repository root URL.
Related
I'm trying to use M2Doc programmatically, I managed to generate my .docx file without getting errors in the validation part but I'm getting the following Error in the generated document:
{m:self.Name} Couldn't find the 'aqlFeatureAccess(org.eclipse.emf.common.util.URI.Hierarchical,java.lang.String)' service
The "self.Name" part is what I wrote in my template.
I think I'm lacking some kind of reference to a service but I don't know how to fix it.
The self variable is a reference to a model based on a meta-model I created. But I'm not sure I imported it correctly in my code.
I based my code on the code I found on the M2Doc website + some code I found on their GitHub, especially concerning how to add a service in the queryEnvironment.
I searched in the source code of acceleo and M2Doc to see which services they add but it seems that they already import all the services I'm using.
As I said, the validation part is going well and doesn't generate a validation file.
public static void parseDocument(String templateName) throws Exception{
final URI templateURI = URI.createFileURI("Template/"+templateName+"."+M2DocUtils.DOCX_EXTENSION_FILE);
final IQueryEnvironment queryEnvironment =
org.eclipse.acceleo.query.runtime.Query.newEnvironmentWithDefaultServices(null);
final Map<String, String> options = new HashMap<>(); // can be empty
M2DocUtils.prepareEnvironmentServices(queryEnvironment, templateURI, options); // delegate to IServicesConfigurator
prepareEnvironmentServicesCustom(queryEnvironment, options);
final IClassProvider classProvider = new ClassProvider(ClassLoader.getSystemClassLoader()); // use M2DocPlugin.getClassProvider() when running inside Eclipse
try (DocumentTemplate template = M2DocUtils.parse(templateURI, queryEnvironment, classProvider)) {
ValidationMessageLevel validationLevel = validateDocument(template, queryEnvironment, templateName);
if(validationLevel == ValidationMessageLevel.OK){
generateDocument(template, queryEnvironment, templateName, "Model/ComplexKaosModel.kaos");
}
}
}
public static void prepareEnvironmentServicesCustom(IQueryEnvironment queryEnvironment, Map<String, String> options){
Set<IService> services = ServiceUtils.getServices(queryEnvironment, FilterService.class);
ServiceUtils.registerServices(queryEnvironment, services);
M2DocUtils.getConfigurators().forEach((configurator) -> {
ServiceUtils.registerServices(queryEnvironment, configurator.getServices(queryEnvironment, options));
});
}
public static void generateDocument(DocumentTemplate template, IQueryEnvironment queryEnvironment,
String templateName, String modelPath)throws Exception{
final Map<String, Object> variable = new HashMap<>();
variable.put("self", URI.createFileURI(modelPath));
final Monitor monitor = new BasicMonitor.Printing(System.out);
final URI outputURI = URI.createFileURI("Generated/"+templateName+".generated."+M2DocUtils.DOCX_EXTENSION_FILE);
M2DocUtils.generate(template, queryEnvironment, variable, outputURI, monitor);
}
The variable "self" contains an URI:
variable.put("self", URI.createFileURI(modelPath));
You have to load your model and set the value of self to an element from your model using something like:
final ResourceSet rs = new ResourceSetImpl();
final Resource r = rs.getResource(uri, true);
final EObject value = r.getContents()...;
variable.put("self", value);
You can get more details on resource loading in the EMF documentation.
I have webapp in Vaadin Framework 8. I have Windows GUI app in C#.
The gui app is using WebBrowser component to display webapp. WebBrowser component is internally using IE11 core through ActiveX. I can successfully load and display the webapp in the gui app browser component.
I need to pass data from webapp to the gui app.
The webapp has many rows loaded on server side, only few are displayed in grid. I want to pass all data from webapp to gui app in some format (csv or json).
I have tryed some approaches, but I wasn't successfull.
[Approach 1]
Webapp: attach downloadable resource (csv) to Link with predefined id using FileDownloader. Download by user mouse click works fine, file save dialog pops up and data are downloaded successfully.
Link link = new Link("Data");
link.setId("myId");
StreamResource resource = getMyResource(data);
FileDownloader downloader = new FileDownloader(resource);
downloader.extend(link);
Page.getCurrent().getJavaScript().addFunction("test", new JavaScriptFunction() {
#Override
public void call(JsonArray arguments) {
Page.getCurrent().getJavaScript()
.execute("document.getElementById('myId').click()");
}
});
Gui app: raise onClick event on link and capture WebBrowser.FileDownload event, capture WebBrowser.Navigate event.
I have failed to raise onClick event from C# using:
HtmlElement el = webBrowser.Document.GetElementById("myId");
el.RaiseEvent("onClick");
el.InvokeMember("click");
webBrowser.Document.InvokeScript("document.getElementById('myId').click();", null);
webBrowser.Document.InvokeScript("test", null);
Result:
WebBrowser.FileDownload event doesn't work (is fired but can't capture url nor data), capture WebBrowser.Navigate event works partialy (can see resource url, but can't download data using byte[] b = new WebClient().DownloadData(e.Url);).
[Approach 2]
Similar to approach 1. I tryed to get resource url, put the direct url to Link and download the resource in c# using direct link. I can construct the same resource url as is used by browser to download data when user clicks the link.
Extended file downloader that keeps resource, key and connector:
public class ExtendedFileDownloader extends FileDownloader {
private String myKey;
private Resource myResource;
private ClientConnector myConnector;
public ExtendedFileDownloader(StreamResource resource, ClientConnector connector) {
super(resource);
myConnector = connector;
}
#Override
protected void setResource(String key, Resource resource) {
super.setResource(key, resource);
myKey = key;
myResource = resource;
}
public String getResourceUrl() {
ResourceReference ref =
ResourceReference.create(
myResource,
(myConnector != null) ? myConnector : this,
myKey);
String url = ref.getURL();
return url;
}
}
In view:
// fix app://path... urls to /<base-path>/path urls
private String fixResourceReferenceUrl(String resourceReferenceUrl) {
String resourceReferencePath = resourceReferenceUrl.replace("app://", "");
String uiBaseUrl = ui.getUiRootPath();
String fixedUrl = uiBaseUrl + "/" + resourceReferencePath;
return fixedUrl;
}
Link link2 = new Link("Data2");
link2.setId("myId2");
StreamResource resource = getMyResource(data);
ExtendedFileDownloader downloader = new ExtendedFileDownloader(resource, this);
String fixedResourceUrl = fixResourceReferenceUrl(downloader.getResourceUrl());
link2.setResource(new ExternalResource(fixedResourceUrl));
Result:
The data cannot be downloaded using this link, server error 410 or NotFound errors.
Any Ideas ? Any other approaches to try ?
I have finally solved the problem. The solution is very close to approach 2.
The resource url is passed in element with custom attribute. C# WebClient needs to set cookies from WebBrowser and Referer HTTP headers. The data can be successfully downloaded by C# app.
Element attribute in vaadin webapp can be set using Vaadin-addon Attributes.
Cookies in C# app can be retrieved using this solution.
// Fix resource urls begining with app://
public String fixResourceReferenceUrl(String resourceReferenceUrl) {
try {
String uiRootPath = UI.getCurrent().getUiRootPath();
URI location = Page.getCurrent().getLocation();
String appLocation = new URIBuilder()
.setScheme(location.getScheme())
.setHost(location.getHost())
.setPort(location.getPort())
.setPath(uiRootPath)
.build()
.toString();
String resourceReferencePath = resourceReferenceUrl.replace("app://", "");
String fixedUrl = appLocation + "/" + resourceReferencePath;
return fixedUrl;
}
catch (Exception e) {
return null;
}
}
In view (using ExtendedFileDownloader from above):
Link link = new Link("Data");
link.setId("myId");
StreamResource resource = getMyResource(data);
ExtendedFileDownloader downloader = new ExtendedFileDownloader(resource);
downloader.extend(link);
Attribute attr = new Attribute("x-my-data", fixResourceReferenceUrl(downloader.getResourceUrl()));
attr.extend(link);
link.setVisible(true);
In C# app:
[DllImport("wininet.dll", SetLastError = true)]
public static extern bool InternetGetCookieEx(
string url,
string cookieName,
StringBuilder cookieData,
ref int size,
Int32 dwFlags,
IntPtr lpReserved);
private const Int32 InternetCookieHttponly = 0x2000;
public static String GetUriCookies(String uri)
{
// Determine the size of the cookie
int datasize = 8192 * 16;
StringBuilder cookieData = new StringBuilder(datasize);
if (!InternetGetCookieEx(uri, null, cookieData, ref datasize, InternetCookieHttponly, IntPtr.Zero))
{
if (datasize < 0)
return null;
// Allocate stringbuilder large enough to hold the cookie
cookieData = new StringBuilder(datasize);
if (!InternetGetCookieEx(
uri,
null, cookieData,
ref datasize,
InternetCookieHttponly,
IntPtr.Zero))
return null;
}
return cookieData.ToString();
}
private void button_Click(object sender, EventArgs e)
{
HtmlElement el = webBrowser.Document.GetElementById("myId");
String url = el.GetAttribute("x-my-data");
String cookies = GetUriCookies(url);
WebClient wc = new WebClient();
wc.Headers.Add("Cookie", cookies);
wc.Headers.Add("Referer", WEB_APP_URL); // url of webapp base path, http://myhost/MyUI
byte[] data = wc.DownloadData(url);
}
I have some code that works properly on spring boot prior to 2 and I find it hard to convert it to work with spring boot 2.
Can somebody assist?
public static MutablePropertySources buildPropertySources(String propertyFile, String profile)
{
try
{
Properties properties = new Properties();
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
// load common properties
PropertySource<?> applicationYamlPropertySource = loader.load("properties", new ClassPathResource(propertyFile), null);
Map<String, Object> source = ((MapPropertySource) applicationYamlPropertySource).getSource();
properties.putAll(source);
// load profile properties
if (null != profile)
{
applicationYamlPropertySource = loader.load("properties", new ClassPathResource(propertyFile), profile);
if (null != applicationYamlPropertySource)
{
source = ((MapPropertySource) applicationYamlPropertySource).getSource();
properties.putAll(source);
}
}
propertySources = new MutablePropertySources();
propertySources.addLast(new PropertiesPropertySource("apis", properties));
}
catch (Exception e)
{
log.error("{} file cannot be found.", propertyFile);
return null;
}
}
public static <T> void handleConfigurationProperties(T bean, MutablePropertySources propertySources) throws BindException
{
ConfigurationProperties configurationProperties = bean.getClass().getAnnotation(ConfigurationProperties.class);
if (null != configurationProperties && null != propertySources)
{
String prefix = configurationProperties.prefix();
String value = configurationProperties.value();
if (null == value || value.isEmpty())
{
value = prefix;
}
PropertiesConfigurationFactory<?> configurationFactory = new PropertiesConfigurationFactory<>(bean);
configurationFactory.setPropertySources(propertySources);
configurationFactory.setTargetName(value);
configurationFactory.bindPropertiesToTarget();
}
}
PropertiesConfigurationFactory doesnt exist anymore and the YamlPropertySourceLoader load method no longer accepts 3 parameters.
(the response is not the same either, when I have tried invoking the new method the response objects were wrapped instead of giving me the direct strings/integers etc...)
The PropertiesConfigurationFactory should be replaced with Binder class.
Binder class
Sample code:-
ConfigurationPropertySource source = new MapConfigurationPropertySource(
loadProperties(resource));
Binder binder = new Binder(source);
return binder.bind("initializr", InitializrProperties.class).get();
We were also using PropertiesConfigurationFactory to bind a POJO to a
prefix of the Environment. In 2.0, a brand new Binder API was
introduced that is more flexible and easier to use. Our binding that
took 10 lines of code could be reduced to 3 simple lines.
YamlPropertySourceLoader:-
Yes, this class has been changed in version 2. It doesn't accept the third parameter profile anymore. The method signature has been changed to return List<PropertySource<?>> rather than PropertySource<?>. If you are expecting single source, please get the first occurrence from the list.
Load the resource into one or more property sources. Implementations
may either return a list containing a single source, or in the case of
a multi-document format such as yaml a source for each document in the
resource.
Since there is no accepted answer yet, i post my full solution, which builds upon the answer from #nationquest:
private ConfigClass loadConfiguration(String path){
MutablePropertySources sources = new MutablePropertySources();
Resource res = new FileSystemResource(path);
PropertiesFactoryBean propFactory = new PropertiesFactoryBean();
propFactory.setLocation(res);
propFactory.setSingleton(false);
// resolve potential references to local environment variables
Properties properties = null;
try {
properties = propFactory.getObject();
for(String p : properties.stringPropertyNames()){
properties.setProperty(p, env.resolvePlaceholders(properties.getProperty(p)));
}
} catch (IOException e) {
e.printStackTrace();
}
sources.addLast(new PropertiesPropertySource("prefix", properties));
ConfigurationPropertySource propertySource = new MapConfigurationPropertySource(properties);
return new Binder(propertySource).bind("prefix", ConfigClass.class).get();
}
The last three lines are the relevant part here.
dirty code but this is how i solved it
https://github.com/mamaorha/easy-wire/tree/master/src/main/java/co/il/nmh/easy/wire/core/utils/properties
I have bellow url :
http://www.example.com/api/Video/GetListMusicRelated/0/0/null/105358/0/0/10/null/null
This section is Fixed and unchangeable:
http://www.example.com/api/Video/GetListMusicRelated/
I set parameter to this url like bellow :
http://www.example.com/api/Video/GetListMusicRelated/25/60/jim/105358/20/1/5/null/null
OR :
http://www.example.com/api/Video/GetListMusicRelated/0/0/null/105358,5875,85547/0/0/10/null/null
How I can write for this url a url builder ?
If you want to create an UrlBuilder using the builder pattern, it could be done like this:
public class UrlBuilder {
private final String root;
private int myParam1;
private String myParam2;
public UrlBuilder(final String root) {
this.root = root;
}
public UrlBuilder myParam1(int myParam1) {
this.myParam1 = myParam1;
return this;
}
public UrlBuilder myParam2(String myParam2) {
this.myParam2 = myParam2;
return this;
}
public URL build() throws MalformedURLException {
return new URL(
String.format("%s/%d/%s", root, myParam1, myParam2)
);
}
}
Then you will be able to create your URL as next
URL url = new UrlBuilder("http://www.example.com/api/Video/GetListMusicRelated")
.myParam1(25)
.myParam2("jim")
.build();
NB: This only shows the idea, so I used fake parameter's name and incorrect number of parameters, please note that you are supposed to have 6 parameters and set the proper names.
try this...
URL domain = new URL("http://example.com");
URL url = new URL(domain + "/abcd/abcd");
I am trying to get the request url without values of path parameters into it.
Consider my complete url is
URl: http://localhost:8080/aaa/mock/abcd/1234/true
Path parameters: abcd, true
Output needed: /aaa/mock/abcd
My web service method looks like this.
#Path(value = "/aaa/mock")
#Component
public class MockService
{
private static Log log = LogFactory.getLog(MockService.class);
//address
#GET
#Path(value = "/{mockrequest}/{status}")
#Produces(MediaType.JSON)
public String mockEngagement(#Context ContainerRequestContext request,#PathParam("mockrequest") String mockrequest,#PathParam("status") String status )
{
log.info("The mock url is"+request.getUriInfo().getRequestUri());
log.info("The mock url is"+request.getUriInfo().getAbsolutePath());
log.info("The mock url is"+request.getUriInfo().getBaseUri());
log.info("The mock url is"+request.getUriInfo().getMatchedURIs());
**//Out put needed /aaa/mock/abcd**
return "ajaja";
}
}
None of the above calls return the required info.
I am thinking if there is a generic process to get the desired output irrespective of number of path parameters.
Any such methods.
Try UriInfo#getPath(), UriInfo#getPath(boolean), or UriInfo#getPathSegments(). The boolean argument is whether the path should be encoded or not.
https://jersey.java.net/apidocs/2.3.1/jersey/index.html
You could also get the absolute path and the base path and then use URI#relativize(URI).
Try this:
request.getUriInfo().getPathSegments().get(0).getPath()
public void filter(ContainerRequestContext context) throws IOException {
Message message = PhaseInterceptorChain.getCurrentMessage();
Set<Map.Entry<String, Object>> o = (Set<Map.Entry<String, Object>>)message.entrySet();
for (Map.Entry<String, Object> oo : o) {
String key = oo.getKey();
Object val = oo.getValue();
// Thises two properties gives the path of web service
//path_to_match_slash
//org.apache.cxf.request.uri
if(key.equals("path_to_match_slash"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
if(key.equals("org.apache.cxf.request.uri"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
}
}
this code could work only for apache cxf rest
we can found path_to_match_slash , org.apache.cxf.request.uri properties in the ContainerRequestContext