[spring-rest-docs]: Problem documenting a Map<Object, Set<Object>> - spring-restdocs

I have a hard time trying to document the following:
{
"virtualFaxPermissions" : {
"SOME_RANDOM_UUID" : [ "SOME_SPECIFIC_PERMISSION" ]
}
}
I have tried to put a reference of the same map I used to construct the object but it didn't help:
final Map<VirtualFaxMachineId, Set<VirtualFaxMachinePermission>> virtualFaxPermissionsSetMap = new HashMap<>();
virtualFaxPermissionsSetMap.put(VirtualFaxMachineId.valueOf(SOME_RANDOM_UUID), Set.of(SOME_SPECIFIC_PERMISSION));
user.setVirtualFaxPersmission(virtualFaxPermissionsSetMap);
.....
fieldWithPath("virtualFaxPermissions").description(virtualFaxPermissionsSetMap)
Error i get is that the part above is not documented in the payload.
org.springframework.restdocs.snippet.SnippetException: The following parts of the payload were not documented:
{
"virtualFaxPermissions" : {
"RANDOM_UUID_GENERATED" : [ "REQUESTED_PERMISSION" ]
}
}
at org.springframework.restdocs.payload.AbstractFieldsSnippet.validateFieldDocumentation(AbstractFieldsSnippet.java:218)
I have tried to document using a wildcard for the UUDI, but that didn't help either
Thanks for any pointers

as per:
https://github.com/spring-projects/spring-restdocs/issues/793
using
subsectionWithPath("virtualFaxPermissions")
did the trick

Related

Getting Document metadata (Document Type values) in liferay 7

I am working on Liferay 7. I created a document type "My Documents" with field "Language" which is a selection dropdown with values "English", "French" and "Spanish". I uploaded a document and selected Language value as French. Now I am trying to get this Language value for the document but its returning blank. Below is the code I am using.
DDMStructure ddmStructure = null;
List<DDMStructure> structures = dLFileEntryType.getDDMStructures();
mainloop:
for (DDMStructure struct : structures) {
if (struct.getName((Locale.ROOT)).equalsIgnoreCase("My Document")) {
ddmStructure = struct;
break mainloop;
}
}
DLFileEntryMetadata fileEntryMetadata = null;
try {
fileEntryMetadata = DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(ddmStructure.getStructureId(), dlFileEntry.getFileVersion().getFileVersionId());
if(Validator.isNotNull(fileEntryMetadata)) {
ServiceContext serviceContextDLFile = new ServiceContext();
serviceContextDLFile.setCompanyId(companyId);
serviceContextDLFile.setAttribute("fileEntryTypeId", fileEntryTypeId);
serviceContextDLFile.setAttribute("fileEntryMetadataId", fileEntryMetadata.getFileEntryMetadataId());
serviceContextDLFile.setAttribute("DDMStorageId", fileEntryMetadata.getDDMStorageId());
serviceContextDLFile.setAttribute("fileEntryId", fileEntryMetadata.getFileEntryId());
serviceContextDLFile.setAttribute("fileVersionId", fileEntryMetadata.getFileVersionId());
DDMFormValues ddmFormValues = StorageEngineManagerUtil.getDDMFormValues(fileEntryMetadata.getDDMStructureId(), null, serviceContextDLFile);
List<DDMFormFieldValue> ddmFormFieldValues = ddmFormValues.getDDMFormFieldValues();
if(Validator.isNotNull(ddmFormFieldValues) && !ddmFormFieldValues.isEmpty()) {
for(DDMFormFieldValue formfieldValue : ddmFormFieldValues) {
if(formfieldValue.getName().equalsIgnoreCase("Language")) {
String languageRawName = formfieldValue.getValue().getString(Locale.US);
String language = languageRawName.replace("[\"", "").replace("\"]", "");
}
}
}
}
} catch (NoSuchFileEntryMetadataException nsfene) {
// LOGGER.error("ERROR:: ", nsfene);
} catch(PortalException portalException) {
// LOGGER.error("ERROR:: " , portalException);
}
I have not given any predefined value for Language field while creating Document Type. When I am giving any predefined value for Language field, the above code is returning that predefined value.
Please tell if I am missing something or there is any other approach do achieve this.
Stored data in document library documents is not internationalized.
I think you have to always use the default language of the instance.

How to map Json object to JPA specification for Search query

I have a RequestMaping that get a Search json class as body params.
I want to create proper Specification from this search json object so that pass to my Repository like this:
pagesResult = myRepository.findAll(mySpec)
I have problme with parsing and Dynamically add items to specification. I want to achieve something like this:
#Override
public Phones searchPhones(int pageNumber, Map<String, String> searchObject) {
List<PhoneSpecification> specificationslist = new ArrayList<>();
generateSpecifications(searchObject, specificationslist); //fill specificationList
Specification<Phone> specificationOfPhone;
for (PhoneSpecification spec :
specificationslist) {
//this is my problem , I had to dynamically increase my Specification like this:
specificationOfPhone = specificationOfPhone + Specifications.and(spec);
}
mobileRepository.findAll(specificationOfPhone);
I finally achieve this by adding where to first specification and handle all by adding like this:
if(specificationslist.size()>0){
finalSpecification = Specifications.where(specificationslist.get(0)) ;
}
for (int i=1 ; i<specificationslist.size(); i++) {
finalSpecification = Specifications.where(finalSpecification).and(specificationslist.get(i));
}
You can change your code to this:
Specifications<Phone> specificationOfPhone = Specifications.where(null);
for (PhoneSpecification spec : specificationslist) {
specificationOfPhone = specificationOfPhone.and(spec);
}
I assumed that PhoneSpecification is extending/implements Specification<T>.
Specifications.where(null); will return empty specification which can be chained with others.
Because Specifications<T> extends Specification<T> you can use it with your findAll method.

How to replace function name with a babel plugin

Is it possible to create a babel plugin that will change some a functions name ?
I can't seems to find this in the documentation.
Example:
myObject.doSomething() ==> babel ==> myObject.___doSomething()
Thanks
You can get the AST of your code in astexplorer. And you can see it's about a CallExpression and MemberExpression. So search babel-types API in babel-types source code, it's very clear of how to create a babel type or judge a babel-type like this:
defineType("MemberExpression", {
builder: ["object", "property", "computed"],
visitor: ["object", "property"],
aliases: ["Expression", "LVal"],
fields: {
object: {
validate: assertNodeType("Expression")
},
property: {
validate(node, key, val) {
let expectedType = node.computed ? "Expression" : "Identifier";
assertNodeType(expectedType)(node, key, val);
}
},
computed: {
default: false
}
}
});
Following are two different ways to do it (either with the Program visitor or with the FunctionDeclaration visitor):
export default function ({types: t}) {
return {
visitor: {
Program(path) {
path.scope.rename('doSomething', '___doSomething');
},
FunctionDeclaration(path) {
if (path.node.id.name === 'doSomething') {
path.node.id.name = '___doSomething'
}
}
}
};
}
Note that these are not safe since they can override an existing name. You can use the path.scope.generateUidIdentifier("uid"); command to generate a unique identifier and use that but you wont be able to define the generated name.
Example - http://astexplorer.net/#/o5NsNwV46z/1

How to find unused images from CQ DAM

Is there a way to find to unused assets from CQ DAM? Currently our CQ instance has accumulated huge amount of assets and at least 25% is not being used as of now. Our CQ instance is running on windows (5.6). Is there a cleaner way to do the same?
Thanks,
Santhosh
You may use the following XPATH query to get all assets:
/jcr:root/content/dam//*[#jcr:primaryType='dam:Asset']
Using QueryManger you may get list of asset nodes:
Workspace workspace = session.getWorkspace();
QueryManager qm = workspace.getQueryManager();
Query query = qm.createQuery(xpathQuery, Query.XPATH);
QueryResult queryResult = query.execute();
result = queryResult.getNodes();
Next you need to get path of every asset and verify is it used:
while(result.hasNext()) {
Node assetNode = result.nextNode();
String assetPath = assetNode.getPath();
}
To verify is it asset used you need again run xpath :
/jcr:root/content/mywebsite//*[#fileReference='putAssetPathHere']
Now result.hasNext() == true means asset is used
Another solution is to use ReferenceSearch
for (String path : paths) {
if (resourceResolver.getResource(path) != null) {
Map<String, ReferenceSearch.Info> searchResult = referenceSearch.search(resourceResolver, path);
if (searchResult.isEmpty()) {
//path is unused asset
}
//get used pages
for (Map.Entry<String, ReferenceSearch.Info> info : searchResult.entrySet()) {
info.getKey();//will return page path
}
//get used properties paths
for (Map.Entry<String, ReferenceSearch.Info> info : searchResult.entrySet()) {
for (String prop : info.getValue().getProperties()) {
//prop is property path
}
}
}
}
For me following code worked.
help link : http://wemcode.wemblog.com/get_asset_reference_in_page
String damPath = "/content/dam/geometrixx/offices/basel kitchen.jpg";
for (ReferenceSearch.Info info: new ReferenceSearch().search(resourceResolver, damPath).values()) {
for (String p: info.getProperties()) {
out.println("Path is "+info.getPage().getPath());
}

Codemirror adding keywords on the fly for syntax highlight

I am currently adding a new language mode in CodeMirror for my current project. This is a proprietary language in which user can create a new keyword. Basically I am trying to update existing keyword list at the runtime and my syntax highlighter can pick this new keyword.
var mode = editor.doc.modeOption;
if(mode === "dmsrl") mode = "text/dmsrl";
var keyWords = CodeMirror.resolveMode(mode).keywords;
keyWords[x]=true;
I am currently trying to add new keyword like above, but somehow the list is not getting updated and new keyword is unavailable in my tokebase() method.
Any help would be appreciated.
You can try to redefine hintOptions object, that pass to Codemirror's init function and than building hints in your specific hint addon with this data. Just try this
cm.setOption("hintOptions", { "keywords" : ["k1", "k2"] });
Look at first in sql-hint for example (link):
cm.setOption("hintOptions", { "tables" : ["k1", "k2"] });
For sql-mode this is not heavy operation
I wanted to reach the same goal as yours but with some more degree of freedom, consisting in inputting a container, which I can re-define along the run.
1) Put the following code into a file custom.mode.js, to be loaded from your web page
var _glob_keywords = [ [ "key1", "keyword1" ],
[ "key2", "keyword2" ]
] ;
var cm_custom_check_stream_fn = function( stream )
{
for( var _i = 0 ; _i < _glob_keywords.length ; _i++ )
{
if ( stream.match( _glob_keywords[_i][0] ) ) return _glob_keywords[_i][1] ;
}
return "" ;
}
CodeMirror.defineMode("custom.mode", function()
{
return {
token: function(stream,state)
{
var _ret = cm_custom_check_stream_fn( stream ) ;
if ( _ret.length > 0 ) return _ret ;
else { stream.next(); return null; }
}
};
});
This code will be automatically embedded into the Codemirror object to dynamically handle the input in the textbox.
Example: if "key1" is found, then "keyword1" is returned.
We assume that "keyword1", "keyword2" refer to entries inside a custom css definitions file, as explained in the codemirror documentation, that is,
.cm-keyword1 { color:#8BA8C4; }
.cm-keyword2 { color:lime; }
Hope it helps!