TinyTree.getNamespaceBindings() failing - saxon

We have upgraded from Saxon EE 9 to 10.1. The following line of code:
private void declareNameSpaces(XdmNode xmlRootNode, XPathCompiler xPath) {
NamespaceBinding[] namespaceBindings = ((TinyDocumentImpl) xmlRootNode.getUnderlyingValue()).getTree().getNamespaceBindings();
Throws the exception:
Caused by: java.lang.UnsupportedOperationException
at net.sf.saxon.tree.tiny.TinyTree.getNamespaceBindings(TinyTree.java:1642)
at net.windward.datasource.xml.SaxonDataSource.declareNameSpaces(SaxonDataSource.java:395)
What do we need to do differently?
The entire code in case you need it is:
private void declareNameSpaces(XdmNode xmlRootNode, XPathCompiler xPath) {
NamespaceBinding[] namespaceBindings = ((TinyDocumentImpl) xmlRootNode.getUnderlyingValue()).getTree().getNamespaceBindings();
List<String> prefixes = new ArrayList<String>();
for (NamespaceBinding namespaceBinding : namespaceBindings) {
if (namespaceBinding == null)
break;
String prefix = namespaceBinding.getPrefix();
if (prefix == null || prefix.isEmpty()) {//use default prefix if prefix is empty.
prefix = defaultPrefix;
// make sure the prefix is unique
while (prefixes.contains(prefix)) {
if (Character.isDigit(prefix.charAt(prefix.length() - 1)))
prefix = prefix.substring(0, prefix.length() - 1) + String.valueOf((int) prefix.charAt(prefix.length() - 1) + 1);
else
prefix = prefix + '1';
}
prefixes.add(prefix);
}
String uri = namespaceBinding.getURI();
if (uri != null && !uri.isEmpty()) {
xPath.declareNamespace(prefix, namespaceBinding.getURI());
prefixNamespaceMap.put(prefix, namespaceBinding);
uriToPrifixeMap.put(namespaceBinding.getURI(), prefix);
}
}
}

You're using what we class as "system programming interfaces" here, which are subject to change from one major release to another. The whole area of namespace representation on the NodeInfo interface changed significantly in 10.0 - see the "changes" section of the documentation for more detail. The model is now closer to the XDM spec, revealing only the in-scope namespaces for a node, and not the "declarations" (i.e. differences from a parent node).
I can't really tell what your code is trying to achieve, especially as it seems to be looking at the namespace bindings for a document node, which will always be empty.
In general with 10.0 you should get namespace information using NamespaceMap getAllNamespaces();

Related

Swashbuckle custom string comparer not applied for order groups of actions

In Swashbuckle there is a setting called OrderActionGroupsBy which is supposed to change the ordering within the API, but nothing I do is working and I'm can't determine whether this is a Swashbuckle problem, or due to my IComparer any idea what I'm doing wrong?
This is setting the configurations
config.EnableSwagger(c =>
{
...
c.OrderActionGroupsBy(new CustomStringComparer());
c.GroupActionsBy(apiDesc => GroupBy(apiDesc));
...
}
This is grouping the actions by type instead of controllerName.
private static string GroupBy(ApiDescription apiDesc)
{
var controllerName = apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName;
var path = apiDesc.RelativePath;
if (controllerName.Contains("Original"))
{
controllerName = controllerName.Replace("Original", "");
}
// Check if it is one of the entities if so group by that
// Otherwise group by controller
var entities = new List<string>() { "Users", "Apps", "Groups" };
var e = entities.Where(x => attr.Contains(x.ToLower())).FirstOrDefault();
if (e != null)
{
return e;
}
return controllerName;
}
This is my attempt at an IComparer I want Users first and then after that alphabetical
class CustomStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x.CompareTo(y) == 0)
return 0;
if (x.CompareTo("Users") == 0)
return -1;
if (y.CompareTo("Users") == 0)
return 1;
return x.CompareTo(y);
}
}
}
This isn't working it always defaults to alphabetical no matter what I do.
Looks like this is a bug with Swashbuckle/Swagger-ui
Using OrderActionGroupsBy is correctly sorting the JSON file, but then swagger ui automatically resorts this to alphabetical order.
I have filed bugs with both Swashbuckle and swagger-ui since this seems to go against what is said in swagger-ui's doc regarding apisSorter.
Apply a sort to the API/tags list. It can be 'alpha' (sort by name) or
a function (see Array.prototype.sort() to know how sort function
works). Default is the order returned by the server unchanged.
Swashbuckle issue
swagger-ui issue
swagger-ui specific stackoverflow question

How do I use SimpleFileVisitor in Java to find a file name whose encoding may vary?

I'm using SimpleFileVisitor to search for a file. It works fine on Windows and Linux. However when I try using it on Unix like operating systems It doesn't work as expected. I would get errors like this:
java.nio.file.NoSuchFileException:
/File/Location/MyFolder/\u0082\u0096\u0096âĜu0099\u0081\u0097K
\u0097\u0099\u0096\u0097\u0085\u0099Ĝu0089\u0085
It looks like the obtained name is in different character encoding and maybe that is what causing the issue. It looks like in between the obtaining the name and trying to obtain the access to the file, the encoding is getting missed up. This result in calling preVisitDirectory once then visitFileFailed for every file it tries to visit. I'm not sure why the walkFileTree method is doing that. Any idea?
My using for SimpleFileVisitor code looks like this:
Files.walkFileTree(serverLocation, finder);
My SimpleFileVisitor class:
public class Finder extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
private final List<Path> matchedPaths = new ArrayList<Path>();
private String usedPattern = null;
Finder(String pattern) {
this.usedPattern = pattern;
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
void match(Path file) { //Compare pattern against file or dir
Path name = file.getFileName();
if (name != null && matcher.matches(name))
matchedPaths.add(file);
}
// Check each file.
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
match(file);
return CONTINUE;
}
// Check each directory.
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
match(dir);
return CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
System.out.println("Issue: " + e );
return CONTINUE;
}
Try using "Charset.defaultCharset()" when you create those "file" and "dir" strings you pass around. Otherwise, you could very likely mangle the names in the process of creating those strings to pass them to your visit methods.
You might also check your default encoding on the JVM your are running, if it is out of sync with the file system you are reading, your results will be, err, unpredictable.

Struts2 convention and redirect parameters

I use a Struts2 Convention plug-in to map my actions. Please, help me to solve the following problem. Here I have an action mapping
#Action(value="/{categorie:\\w+}/{hoofdgroep:\\w+}/{artikelgroep:\\w+}/", results = {
#Result(name="success", location="articlelist.jsp"),
#Result(name="maingroup", location="/%{categorie}/%{hoofdgroep}/", type="redirect"),
#Result(name="category", location="/%{categorie}/", type="redirect")
}, interceptorRefs = {
...
})
public String execute() throws Exception {
...
Category category = service.getCategory(categorie);
if (category == null) return NONE;
...
MainGroup mGroup = service.getMainGroup(hoofdgroep);
if (mGroup == null) return "category";
...
ArticleGroup artGroup = service.getArticleGroup(artikelgroep);
if (artGroup == null) return "maingroup";
...
return SUCCESS;
}
When, for instance, there is no artGroup for specified artikelgroep it should redirect link _http://site/categorie/hoofdgroep/artikelgroep/ to url _http://site/categorie/hoofdgroep/ which it perfectly does. The only problem here is that it also prepends additional parameters which are undesired. So link _http://site/categorie/hoofdgroep/artikelgroep/ is redirected to _http://site/categorie/hoofdgroep/?categorie=categorie&hoofdgroep=hoofdgroep&artikelgroep=artikelgroep.
My question is How to get rid of these parameters?
Here are some config params from my struts.properties file
...
struts.serve.static=false
struts.ognl.allowStaticMethodAccess=true
struts.enable.DynamicMethodInvocation=false
struts.action.extension= ,
struts.url.includeParams=none
struts.enable.SlashesInActionNames=true
struts.mapper.alwaysSelectFullNamespace=false
struts.patternMatcher=regex
struts.convention.default.parent.package=app-default
struts.convention.action.packages=...
struts.convention.action.alwaysMapExecute=false
struts.convention.package.locators.disable=true
struts.convention.relative.result.types=dispatcher
struts.convention.result.path=/WEB-INF/jsp/
So basically is this a bug or it should work this way?
Perhaps it is not so elegant solution but here what I have done. I overrode org.apache.struts2.dispatcher.ServletRedirectResult#getProhibitedResultParams
public class ServletRedirectResult
extends org.apache.struts2.dispatcher.ServletRedirectResult
{
public ServletRedirectResult() {
super();
initProhibitedResultParams();
}
public ServletRedirectResult(String location) {
super(location);
initProhibitedResultParams();
}
public ServletRedirectResult(String location, String anchor) {
super(location, anchor);
initProhibitedResultParams();
}
private List<String> prohibitedParamNames;
private void initProhibitedResultParams() {
String[] parentParams = (String[])super.getProhibitedResultParams().toArray();
int len = parentParams.length;
String[] params = new String[len + 4];
for (int i = 0; i < len; i++) {
params[i] = parentParams[i];
}
params[len] = "statusCode";
// TODO: This is a temporary solution because RegexPatternMatcher puts parameters
// from urls into ResultConfig for some reason.
params[len+1] = "categorie";
params[len+2] = "hoofdgroep";
params[len+3] = "artikelgroep";
prohibitedParamNames = Arrays.asList(params);
}
protected List<String> getProhibitedResultParams() {
return prohibitedParamNames;
}
}
What you describe is the default behaviour of both com.opensymphony.xwork2.util.NamedVariablePatternMatcher and org.apache.struts2.util.RegexPatternMatcher however it not the behaviour of com.opensymphony.xwork2.util.WildcardHelper (which is the default implementation)
From what you have shown the default implementation can handle what you are doing with far less headaches (regular wildcard matching).
Consulting this page: http://struts.apache.org/2.3.1.2/docs/wildcard-mappings.html
It states for "Parameters in namespaces" (I know you are not using this):
From Struts 2.1+ namespace patterns can be extracted as request
parameters and bound to the action.
However this equally applies to what is happening in the action and it really seems to be the only behaviour (where I would assume from "can be" that there would be another choice when it should have really been written as "... namespace/action patterns are extracted as request parameters...") and it seems to apply to the regex pattern matching equally, it would be nice for the documentation to more explicitly state this.
From your comments I can better understand what you are doing...
Why don't you simply set up three actions for:
*/*/*, */* and *
Then just pass the numbered parameters into the action?
I was digging into the code of org.apache.struts2.dispatcher.ServletRedirectResult#doExecute. Probably this piece prepends undesired parameters
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode());
if (resultConfig != null)
{
Map<String, String> resultConfigParams = resultConfig.getParams();
for (Map.Entry<String, String> e : resultConfigParams.entrySet())
{
if (!getProhibitedResultParams().contains(e.getKey()))
{
String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation);
if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0)))
{
requestParameters.put(e.getKey(), potentialValue);
}
}
}
}
There is nothing wrong with this code. And the question is Why those three parameters appeared in the ResultConfig? Because it is working like, when you write like so
<result name="maingroup" type="redirect">
<param name="location">/${categorie}/${hoofdgroep}/</param>
<param name="namespace">/</param>
<param name="categorie">${categorie}</param>
<param name="hoofdgroep">${hoofdgroep}</param>
<param name="artikelgroep">${artikelgroep}</param>
</result>

Looking for a build activity which breaks a build when new warnings are introduced

We're attempting to clean up a big bunch of brown field code, while at the same time a team is adding new functionality. We'd like to make sure changed and new code is cleaned from any compiler/code analysis or other warnings, but there's too many of them to begin by cleaning up the current solution.
We're using TFS 2010.
So the following was proposed:
Write/select a build activity which compares the list of warnings in the build against the lines of code that changed with that check-in.
If the warning provides a line number, and that line number was changed, fail the build.
I understand this will not find all new warnings and things introduced in other parts of the code will not be flagged, but it's at least something.
Another option that was proposed:
Compare the list of warnings of the previous known good build against the list of this build. If there are new warnings (track on file name level), fail the build.
Any known Actions out there that might provide said functionality?
Any similar Actions that can act on Code Coverage reports?
This following activity is just a basic approach, that returns false if your current build has less or equal warnings than your last build and true if they have risen.Another activity that can locate new warnings and/or present with their location in code would clearly be superior, yet I thought this might be an interesting startpoint:
using System;
using System.Activities;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow.Activities;
namespace CheckWarnings
{
[BuildActivity(HostEnvironmentOption.Agent)]
public sealed class CheckWarnings : CodeActivity<bool>
{
[RequiredArgument]
public InArgument<IBuildDetail> CurrentBuild { get; set; } //buildDetail
public InArgument<string> Configuration { get; set; } //platformConfiguration.Configuration
public InArgument<string> Platform { get; set; } //platformConfiguration.Platform
protected override bool Execute(CodeActivityContext context)
{
IBuildDetail currentBuildDetail = context.GetValue(CurrentBuild);
string currentConfiguration = context.GetValue(Configuration);
string currentPlatform = context.GetValue(Platform);
Uri lastKnownGoodBuildUri = currentBuildDetail.BuildDefinition.LastGoodBuildUri;
IBuildDetail lastKnownGoodBuild = currentBuildDetail.BuildServer.GetBuild(lastKnownGoodBuildUri);
int numOfCurrentWarnings = GetNumberOfWarnings(currentBuildDetail, currentConfiguration, currentPlatform);
context.TrackBuildMessage("Current compile presents " + numOfCurrentWarnings + " warnings.", BuildMessageImportance.Normal);
int numOfLastGoodBuildWarnings = GetNumberOfWarnings(lastKnownGoodBuild, currentConfiguration,
currentPlatform);
context.TrackBuildMessage("Equivalent last good build compile presents " + numOfLastGoodBuildWarnings + " warnings.", BuildMessageImportance.Normal);
if (numOfLastGoodBuildWarnings < numOfCurrentWarnings)
{
return true;
}
return false;
}
private static int GetNumberOfWarnings(IBuildDetail buildDetail, string configuration, string platform)
{
var buildInformationNodes =
buildDetail.Information.GetNodesByType("ConfigurationSummary");
foreach (var buildInformationNode in buildInformationNodes)
{
string localPlatform, numOfWarnings;
string localConfiguration = localPlatform = numOfWarnings = "";
foreach (var field in buildInformationNode.Fields)
{
if (field.Key == "Flavor")
{
localConfiguration = field.Value;
}
if (field.Key == "Platform")
{
localPlatform = field.Value;
}
if (field.Key == "TotalCompilationWarnings")
{
numOfWarnings = field.Value;
}
}
if(localConfiguration == configuration && localPlatform == platform)
{
return Convert.ToInt32((numOfWarnings));
}
}
return 0;
}
}
}
Note that this activity doesn't provide with exception handling and should further be refined, in case your build definitions build more than one solutions.It takes three input args (buildDetail, platformConfiguration.Configuration and platformConfiguration.Platform) and should be placed directly after the Run MSBuild activity.

Field max length in Entity framework

I need to put a max length on my test field on my Views using ASP.NET MVC with the Entity Framework and I can't find how to get the max length of a varchar field.
Is there an easy way to get that, or any other property of a database field
Here is how i manage to do it (with an extension method on entities) :
public static int? GetMaxLength(this EntityObject entite, string nomPropriete)
{
int? result = null;
using (XEntities contexte = XEntities.GetCurrentContext())
{
var queryResult = from meta in contexte.MetadataWorkspace.GetItems(DataSpace.CSpace)
.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType)
from p in (meta as EntityType).Properties
.Where(p => p.DeclaringType.Name == entite.GetType().Name
&& p.Name == nomPropriete
&& p.TypeUsage.EdmType.Name == "String")
select p.TypeUsage.Facets["MaxLength"].Value;
if (queryResult.Count() > 0)
{
result = Convert.ToInt32(queryResult.First());
}
}
return result;
}
Update
I realize that this answer doesn't directly apply to EF. At the time that I answered, there had been no answers for about 20 minutes and I thought knowing how I solved a similar problem with LINQToSQL might help. Given that the OP basically used the same technique albeit with EF properties instead, seems to indicate that I made the right choice. I'm leaving this answer here for context and for those who get here having the same problem but with LINQToSQL.
Original
I don't know about EF, but LINQToSQL entity properties are decorated with ColumnAttributes. You may be able to get the ColumnAttribute from the PropertyInfo for the property by looking at the CustomAttributesCollection. The value of this attribute would need to be parsed for length. I do that in my validator classes to make sure that I'm not going to get a SQL error by using a string that is too long for my column.
This is the method I use to extract the column length for string properties.
public static int MaximumPropertyLength( Type type, string propertyName )
{
int maximumLength = -1;
PropertyInfo info = type.GetProperty( propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance );
if (info != null)
{
var attribute = info.GetCustomAttributes( typeof( ColumnAttribute ), false )
.Cast<ColumnAttribute>()
.FirstOrDefault();
if (attribute != null)
{
maximumLength = ExtractLength( attribute.DbType );
}
}
return maximumLength;
}
private static int ExtractLength( string dbType )
{
int max = int.MaxValue;
if (dbType.Contains( "(" ))
{
string[] parts = dbType.Split( new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries );
if (parts.Length > 1)
{
int.TryParse( parts[1], out max );
}
}
return max;
}
For EntityFramework you would need to add your own custom attributes to the classes using a Code Generator or T4 Template.
Then what tvanfosson stated above would hold true. EF does not persist this information by default.
http://blogs.msdn.com/adonet/archive/2008/01/24/customizing-code-generation-in-the-ado-net-entity-designer.aspx
Explains more of what I am talking about with your code generator. It is pretty slick I have done exactly what you are mentioning before, problem is with proprietary code so I do not have an example for you.

Resources