Creating multiple mandatory fields in workflow - youtrack

I have a requirement for multiple fields to be set whenever an issue is created.
I tried this
rule Mandatory
when <issue created or updated> {
Swimlane.required("Must have a swimlane");
UtgmsVehicleName.required("Must be attached to a vehicle ");
Subsystem.required("Subsystem must be set");
Assignee.required("Assignee must be set");
Fix versions.required("Fix versions must be set/");
}
What happens is that it continually asks for all the fields to be set. What is the best way to fulfil the requirement.
Based on Alex's suggestion i got this
rule MandatoryFields
when !isReported() {
var assigneeSet = Assignee != null;
var subSystemSet = Subsystem != null && Subsystem != {No subsystem};
var fixedVersionSet = Fix versions != null;
var assigneeValue = Assignee.oldValue;
var messageValue = "Mandatory fields:";
if (!assigneeSet) {
messageValue = messageValue + " Assignee";
}
if (!subSystemSet) {
messageValue = messageValue + " Subsystem";
}
if (!fixedVersionSet) {
messageValue = messageValue + " FixedVersion";
}
assert (assigneeSet && subSystemSet && fixedVersionSet): messageValue;
if (assigneeSet) {
Assignee = assigneeValue;
}
}

You can have something like
var noSwimlane = Swimlane == null;
var noSubsystem = Subsystem == null;
...
var message = "You need to fill the following fields: ";
if (noSwimlane) {
message += "Swimlane";
}
...
assert !(noSwimlane || noSubsystem || ...) : message;

Related

How to fix '0 level missing for abstractListDefinition 0' error when using Emulator.getNumber()

I used docx4j to read the docx file. And I need to read the paragraph number format characters. I use Emulator.getNumber() to process, but I got this error. How should I deal with it?
try {
PPr pPr = ((P) p).getPPr();
if (pPr != null && pPr.getNumPr() != null) {
Emulator.ResultTriple triple = Emulator.getNumber(wordprocessingMLPackage, pPr);
if (triple != null) {
order = triple.getNumString();
}
}
} catch (Exception e) {
// throw error '0 level missing for abstractListDefinition 0'
e.printStackTrace();
}
Any help would be appreciated.Thanks.
docx4j version: 6.1.2
docx4j's html output uses it like so:
// Numbering
String numberText=null;
String numId=null;
String levelId=null;
if (pPrDirect.getNumPr()!=null) {
numId = pPrDirect.getNumPr().getNumId()==null ? null : pPrDirect.getNumPr().getNumId().getVal().toString();
levelId = pPrDirect.getNumPr().getIlvl()==null ? null : pPrDirect.getNumPr().getIlvl().getVal().toString();
}
ResultTriple triple = org.docx4j.model.listnumbering.Emulator.getNumber(
conversionContext.getWmlPackage(), pStyleVal, numId, levelId);
if (triple==null) {
getLog().debug("computed number ResultTriple was null");
} else {
if (triple.getBullet() != null) {
//numberText = (triple.getBullet() + " ");
numberText = "\u2022 ";
} else if (triple.getNumString() == null) {
getLog().error("computed NumString was null!");
numberText = ("?");
} else {
numberText = (triple.getNumString() + " ");
}
}
if (numberText!=null) {
currentParent.appendChild(document.createTextNode(
numberText + " "));
}
XSL-FO output:
if (pPrDirect!=null && pPrDirect.getNumPr()!=null) {
triple = org.docx4j.model.listnumbering.Emulator.getNumber(
conversionContext.getWmlPackage(), pStyleVal,
pPrDirect.getNumPr().getNumId().getVal().toString(),
pPrDirect.getNumPr().getIlvl().getVal().toString() );
} else {
// Get the effective values; since we already know this,
// save the effort of doing this again in Emulator
Ilvl ilvl = pPr.getNumPr().getIlvl();
String ilvlString = ilvl == null ? "0" : ilvl.getVal().toString();
triple = null;
if (pPr.getNumPr().getNumId()!=null) {
triple = org.docx4j.model.listnumbering.Emulator.getNumber(
conversionContext.getWmlPackage(), pStyleVal,
pPr.getNumPr().getNumId().getVal().toString(),
ilvlString );
}
}

Use Cecil to insert begin/end block around functions

this simple code works fine and allows to add a BeginSample/EndSample call around each Update/LateUpdate/FixedUpdate function. However it doesn't take in consideration early return instructions, for example as result of a condition. Do you know how to write a similar function that take in considerations early returns so that the EndSample call will be executed under every circumstance?
Note that I am not a Cecil expert, I am just learning now. It appears to me that Cecil automatically updates the operations that returns early after calling InsertBefore and similar functions. So if a BR opcode was previously jumping to a specific instruction address, the address will be updated after the insertions in order to jump to the original instruction. This is OK in most of the cases, but in my case it means that an if statement would skip the last inserted operation as the BR operation would still point directly to the final Ret instruction. Note that Update, LateUpdate and FixedUpdate are all void functions.
foreach (var method in type.Methods)
{
if ((method.Name == "Update" || method.Name == "LateUpdate" || method.Name == "FixedUpdate") &&
method.HasParameters == false)
{
var beginMethod =
module.ImportReference(typeof (Profiler).GetMethod("BeginSample",
new[] {typeof (string)}));
var endMethod =
module.ImportReference(typeof (Profiler).GetMethod("EndSample",
BindingFlags.Static |
BindingFlags.Public));
Debug.Log(method.Name + " method found in class: " + type.Name);
var ilProcessor = method.Body.GetILProcessor();
var first = method.Body.Instructions[0];
ilProcessor.InsertBefore(first,
Instruction.Create(OpCodes.Ldstr,
type.FullName + "." + method.Name));
ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, beginMethod));
var lastRet = method.Body.Instructions[method.Body.Instructions.Count - 1];
ilProcessor.InsertBefore(lastRet, Instruction.Create(OpCodes.Call, endMethod));
changed = true;
}
}
as a Bonus, if you can explain to me the difference between Emit and Append a newly created instruction with the same operand. does Append execute an Emit under the hood or does something more?
I may have found the solution, at least apparently it works. I followed the code used to solve a similar problem from here:
https://groups.google.com/forum/#!msg/mono-cecil/nE6JBjvEFCQ/MqV6tgDCB4AJ
I adapted it for my purposes and it seemed to work, although I may find out other issues. This is the complete code:
static bool ProcessAssembly(AssemblyDefinition assembly)
{
var changed = false;
var moduleG = assembly.MainModule;
var attributeConstructor =
moduleG.ImportReference(
typeof(RamjetProfilerPostProcessedAssemblyAttribute).GetConstructor(Type.EmptyTypes));
var attribute = new CustomAttribute(attributeConstructor);
var ramjet = moduleG.ImportReference(typeof(RamjetProfilerPostProcessedAssemblyAttribute));
if (assembly.HasCustomAttributes)
{
var attributes = assembly.CustomAttributes;
foreach (var attr in attributes)
{
if (attr.AttributeType.FullName == ramjet.FullName)
{
Debug.LogWarning("<color=yellow>Skipping already-patched assembly:</color> " + assembly.Name);
return false;
}
}
}
assembly.CustomAttributes.Add(attribute);
foreach (var module in assembly.Modules)
{
foreach (var type in module.Types)
{
// Skip any classes related to the RamjetProfiler
if (type.Name.Contains("AssemblyPostProcessor") || type.Name.Contains("RamjetProfiler"))
{
// Todo: use actual type equals, not string matching
Debug.Log("Skipping self class : " + type.Name);
continue;
}
if (type.BaseType != null && type.BaseType.FullName.Contains("UnityEngine.MonoBehaviour"))
{
foreach (var method in type.Methods)
{
if ((method.Name == "Update" || method.Name == "LateUpdate" || method.Name == "FixedUpdate") &&
method.HasParameters == false)
{
var beginMethod =
module.ImportReference(typeof(Profiler).GetMethod("BeginSample",
new[] { typeof(string) }));
var endMethod =
module.ImportReference(typeof(Profiler).GetMethod("EndSample",
BindingFlags.Static |
BindingFlags.Public));
Debug.Log(method.Name + " method found in class: " + type.Name);
var ilProcessor = method.Body.GetILProcessor();
var first = method.Body.Instructions[0];
ilProcessor.InsertBefore(first,
Instruction.Create(OpCodes.Ldstr,
type.FullName + "." + method.Name));
ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, beginMethod));
var lastcall = Instruction.Create(OpCodes.Call, endMethod);
FixReturns(method, lastcall);
changed = true;
}
}
}
}
}
return changed;
}
static void FixReturns(MethodDefinition med, Instruction lastcall)
{
MethodBody body = med.Body;
var instructions = body.Instructions;
Instruction formallyLastInstruction = instructions[instructions.Count - 1];
Instruction lastLeaveInstruction = null;
var lastRet = Instruction.Create(OpCodes.Ret);
instructions.Add(lastcall);
instructions.Add(lastRet);
for (var index = 0; index < instructions.Count - 1; index++)
{
var instruction = instructions[index];
if (instruction.OpCode == OpCodes.Ret)
{
Instruction leaveInstruction = Instruction.Create(OpCodes.Leave, lastcall);
if (instruction == formallyLastInstruction)
{
lastLeaveInstruction = leaveInstruction;
}
instructions[index] = leaveInstruction;
}
}
FixBranchTargets(lastLeaveInstruction, formallyLastInstruction, body);
}
private static void FixBranchTargets(
Instruction lastLeaveInstruction,
Instruction formallyLastRetInstruction,
MethodBody body)
{
for (var index = 0; index < body.Instructions.Count - 2; index++)
{
var instruction = body.Instructions[index];
if (instruction.Operand != null && instruction.Operand == formallyLastRetInstruction)
{
instruction.Operand = lastLeaveInstruction;
}
}
}
basically what it does is to add a Ret instuction, but then replace all the previous Ret (usually one, why should it be more than one?) with a Leave function (don't even know what it means :) ), so that all the previous jumps remain valid. Differently than the original code, I make the Leave instruction point to the EndSample call before the last Ret

Creating/Retrieving a Cart programmatically

For a module that I'm writing I need to retrieve a cart for a certain user (not necessary registered) after that a link is called and some data are passed.
My idea was to receive back a previously id passed that can help me to identify a certain cart.
My big problem is that I've search a lot for code cart creation into prestashop. Finally I've found something into
/* Cart already exists */
if ((int)$this->context->cookie->id_cart)
{
$cart = new Cart($this->context->cookie->id_cart);
if ($cart->OrderExists())
{
unset($this->context->cookie->id_cart, $cart, $this->context->cookie->checkedTOS);
$this->context->cookie->check_cgv = false;
}
/* Delete product of cart, if user can't make an order from his country */
elseif (intval(Configuration::get('PS_GEOLOCATION_ENABLED')) &&
!in_array(strtoupper($this->context->cookie->iso_code_country), explode(';', Configuration::get('PS_ALLOWED_COUNTRIES'))) &&
$cart->nbProducts() && intval(Configuration::get('PS_GEOLOCATION_NA_BEHAVIOR')) != -1 &&
!FrontController::isInWhitelistForGeolocation() &&
!in_array($_SERVER['SERVER_NAME'], array('localhost', '127.0.0.1')))
unset($this->context->cookie->id_cart, $cart);
// update cart values
elseif ($this->context->cookie->id_customer != $cart->id_customer || $this->context->cookie->id_lang != $cart->id_lang || $currency->id != $cart->id_currency)
{
if ($this->context->cookie->id_customer)
$cart->id_customer = (int)($this->context->cookie->id_customer);
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)$currency->id;
$cart->update();
}
/* Select an address if not set */
if (isset($cart) && (!isset($cart->id_address_delivery) || $cart->id_address_delivery == 0 ||
!isset($cart->id_address_invoice) || $cart->id_address_invoice == 0) && $this->context->cookie->id_customer)
{
$to_update = false;
if (!isset($cart->id_address_delivery) || $cart->id_address_delivery == 0)
{
$to_update = true;
$cart->id_address_delivery = (int)Address::getFirstCustomerAddressId($cart->id_customer);
}
if (!isset($cart->id_address_invoice) || $cart->id_address_invoice == 0)
{
$to_update = true;
$cart->id_address_invoice = (int)Address::getFirstCustomerAddressId($cart->id_customer);
}
if ($to_update)
$cart->update();
}
}
if (!isset($cart) || !$cart->id)
{
$cart = new Cart();
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)($this->context->cookie->id_currency);
$cart->id_guest = (int)($this->context->cookie->id_guest);
$cart->id_shop_group = (int)$this->context->shop->id_shop_group;
$cart->id_shop = $this->context->shop->id;
if ($this->context->cookie->id_customer)
{
$cart->id_customer = (int)($this->context->cookie->id_customer);
$cart->id_address_delivery = (int)(Address::getFirstCustomerAddressId($cart->id_customer));
$cart->id_address_invoice = $cart->id_address_delivery;
}
else
{
$cart->id_address_delivery = 0;
$cart->id_address_invoice = 0;
}
// Needed if the merchant want to give a free product to every visitors
$this->context->cart = $cart;
CartRule::autoAddToCart($this->context);
}
that is contained into FrontController.php (that seems to be called in every page). So, to me, a cart should always be present during a "user session".
But - yes, there's a but - when I try to retrieve a cart (in that way, into controller of my module)
$context=Context::getContext();
$id_cart=$context->cart->id;
$id_cart isn't there, so cart seems to miss. So I'm a little bit confused.
What's goin' on here? Someone could give me some pointers?
PS.:
I've tried to replicate that function (only the else part) but it doesn't work
You can force cart generation when the user isn't logged in and there is no product in the cart:
$context = Context::getContext();
if (!$context->cart->id) {
$context->cart->add();
$context->cookie->id_cart = $context->cart->id;
}
$id_cart = $context->cart->id;
Take a look at the processChangeProductInCart method in controllers/front/CartController.php
I'm using Prestashop 1.6, and #yenshiraks answer did not work for me. I cannot use $context->cart->add();, because $context->cartis null.
This is what worked in my case:
$context = Context::getContext();
$cart_id = null
if($context->cookie->id_cart) {
$cart = new Cart($context->cookie->id_cart);
$cart_id = $cart->id; // just in case the cookie contains an invalid cart_id
}
if(empty($cart_id)) {
$cart = new Cart();
$cart->id_lang = (int)$context->cookie->id_lang;
$cart->id_currency = (int)$context->cookie->id_currency;
$cart->id_guest = (int)$context->cookie->id_guest;
$cart->id_shop_group = (int)$context->shop->id_shop_group;
$cart->id_shop = $context->shop->id;
$cart->add();
$cart_id = $cart->id;
}
$context->cookie->id_cart = $cart_id;
To answer the question at the end: Even though a cart is always generated in the FrontController, it is not saved to the database, therefore the id is null.
If you are in a context, where the FrontController is instantiated (any page of the frontend, $context->cart->add(); will suffice to save an empty cart to the database.
If on the other hand, you are in a script, that is called directly (like prestashop/modules/my_module/script.php), you have to use the above code.

Permissions used by other app in android

I want to add a feature in my Android app that can check permissions used by other installed apps. For Example: - My app check other already installed apps permissions that which they are used?
StringBuffer appNameAndPermissions=new StringBuffer();
PackageManager pm = getPackageManager();
List <ApplicationInfo>packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
{
for (ApplicationInfo applicationInfo : packages) {
Log.d("test", "App: " + applicationInfo.name + " Package: " + applicationInfo.packageName);
try {
PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);
appNameAndPermissions.append(packageInfo.packageName+"*:\n");
// Get Permissions
String[] requestedPermissions = packageInfo.requestedPermissions;
if(requestedPermissions != null) {
for (int i = 0; i < requestedPermissions.length; i++) {
Log.d("test", requestedPermissions[i]);
appNameAndPermissions.append(requestedPermissions[i]+"\n");
}
appNameAndPermissions.append("\n");
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}}}
}
This is working code, it gives complete list of all permissions used by all apps.
But my question is how to know particularly which app using which permission ?
Please help me & give me some idea about this.
This is Working code:
PackageManager mPm = getPackageManager();
List <PackageInfo> appList=mPm.getInstalledPackages(PackageManager.GET_PERMISSIONS|PackageManager.GET_RECEIVERS|
PackageManager.GET_SERVICES|PackageManager.GET_PROVIDERS);
for (PackageInfo pi : appList) {
System.out.println("Process Name: "+pi);
// Do not add System Packages
if ((pi.requestedPermissions == null || pi.packageName.equals("android")) ||
(pi.applicationInfo != null && (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0))
continue;
for (String permission : pi.requestedPermissions) {
//Map<String, String> curChildMap = new HashMap<String, String>();
//System.out.println("############ "+permission);
try {
PermissionInfo pinfo = mPm.getPermissionInfo(permission, PackageManager.GET_META_DATA);
CharSequence label = pinfo.loadLabel(mPm);
CharSequence desc = pinfo.loadDescription(mPm);
System.out.println("$$$$$ "+label+"!!!!!! "+desc);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission " + permission);
continue;
}
}

SWFAddress 2.2 isn't responding to specific URLs

I am implementing SWFAddress into a Flash movie, and while my navigation is setting the links correctly, when I type in a specific URL, it doesn't seem to communicate with the browser at all. Am I missing a listener or something?
http://client.deicreative.com/test/TBB/
This class talks to my navigation class:
import SWFAddress.as;
class code.RunSWFAddress {
public function RunSWFAddress(){
init();
}
private function init() {
var scope = this;
SWFAddress.setStrict(false);
SWFAddress.onChange = function() {
var value = SWFAddress.getValue();
var path = SWFAddress.getPath();
var id = SWFAddress.getParameter('id');
if (code.PageContent.getInstance().xmlVar1.getBytesLoaded() == code.PageContent.getInstance().xmlVar1.getBytesTotal()){
if(SWFAddress.getValue() == '/' || SWFAddress.getValue() == '') {
code.Navigation.getInstance().showPage(0);
} else {
for(var i:Number = 0; i<code.Startup.getInstance().numPages; i++){
if(SWFAddress.getValue() == code.Startup.getInstance().page_arr[i][0]){
code.Navigation.getInstance().showPage(i);
}
}
}
}
var title = 'The Broadway Building';
var names = SWFAddress.getPathNames();
for (var i = 0; i < names.length; i++) {
title += ' | ' + names[i].substr(0,1).toUpperCase() + names[i].substr(1);
}
var id = SWFAddress.getParameter('id');
if (id != '') {
title += ' | ' + id;
}
SWFAddress.setTitle(title);
}
}
}
I was missing the id attribute in my swfobject embed. Works now! :)