Gradle custom task implementation: could not find method for arguments - gradle

I have an encryption task that receives an input file and an output file along with the key to perform encryption against. The strange thing is that when I try in extract a method that performs a line encryption and receives it as an argument, I get the next error: Could not find method encryptLine() for arguments [PK] on task ':presentation:encryptScenarios' of type EncryptionTask..
When I inline this method - it works ok.
Here is a code of the inlined variant:
#TaskAction
void encryptFile() {
assertThatEncryptionKeyIsPresent()
createNewOutputFileIfNotExists()
final FileOutputStream outputStream = new FileOutputStream(outputFile)
inputFile.eachLine { String line ->
final byte[] inputBytes = line.getBytes()
final byte[] secretBytes = key.getBytes()
final byte[] outputBytes = new byte[inputBytes.length]
int spos = 0
for (int pos = 0; pos < inputBytes.length; ++pos) {
outputBytes[pos] = (byte) (inputBytes[pos] ^ secretBytes[spos])
spos += 1
if (spos >= secretBytes.length) {
spos = 0
}
}
outputStream.write(Base64.encodeBase64String(outputBytes).getBytes())
}
}
And here is the code of the extracted method variant:
#TaskAction
void encryptFile() {
assertThatEncryptionKeyIsPresent()
createNewOutputFileIfNotExists()
final FileOutputStream outputStream = new FileOutputStream(outputFile)
inputFile.eachLine { String line ->
byte[] outputBytes = encryptLine(line)
outputStream.write(Base64.encodeBase64String(outputBytes).getBytes())
}
}
private byte[] encryptLine(String line) {
final byte[] inputBytes = line.getBytes()
final byte[] secretBytes = key.getBytes()
final byte[] outputBytes = new byte[inputBytes.length]
int spos = 0
for (int pos = 0; pos < inputBytes.length; ++pos) {
outputBytes[pos] = (byte) (inputBytes[pos] ^ secretBytes[spos])
spos += 1
if (spos >= secretBytes.length) {
spos = 0
}
}
outputBytes
}
How to resolve this issue using this private method that encrypts a line?

This error seems to be connected to a Groovy issue referenced here : https://issues.apache.org/jira/browse/GROOVY-7797
You are trying to call a private method from a closure within the same class and it looks like this is not supported.
Please try to remove the private modifier from encryptLine method definition, and you should get rid of this error.

Related

Is there a way to avoid the truncation of attached properties when using Appcenter with Xamarin?

Here's my code:
Crashes.TrackError(ex,
new Dictionary<string, string> {
{"RunQuery", "Exception"},
{"sql", s },
{"Device Model", DeviceInfo.Model },
{"Exception", ex.ToString()}
});
Everything works but I find that Appcenter limits the length of the parameters to 125 characters so it's useless for me as I can never see all of the sql or the ex string.
Has anyone found a way to get around this?
I ran into the same problem. My solution was to break my string into groups of 125 character strings and iterate through while logging. I chatted with AppCenter support. They have no way of extending this length currently.
Here is a scrubbed version of my code:
var tokenChunks = LoggingHelper.SplitBy(extremelyLongString, 120);
string title = "Long string here";
var props = new Dictionary<string, string>();
int item = 0;
foreach(string chunk in tokenChunks)
{
string chunkIndex = string.Format("item: {0}", item++);
props.Add(chunkIndex, chunk);
}
Analytics.TrackEvent(title, props);
Where the LoggingHelper class is:
public static class LoggingHelper
{
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
}
I should give credit to this post https://stackoverflow.com/a/8944374/117995 by #oleksii for the SplitBy method.

No need to check this! skip

So what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute isSo what I'm trying to do but clearly struggling to execute is
a single line in the text f
import java.util.Scanner;
import java.io.*;
public class hello
{
public static void main(String[] args) throws IOException
{
Scanner Keyboard = new Scanner(System.in);
System.out.print();
String response = Keyboard.nextLine();
File inFile = new File(response);
Scanner route = new Scanner(inFile);
while ()
{
System.out.print(");
String word = Keyboard.next();
String Street = route.next();
String stopNum = route.next();
You are closing your file after you read one "line" (actually, I'm not sure how many lines you're reading - you don't call nextLine). You also aren't parsing the line. Also, I'd prefer a try-with-resources over an explicit close (and many of your variables look like class names). Finally, you need to check if the line matches your criteria. That might be done like,
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter filename >> ");
String response = keyboard.nextLine();
File inFile = new File(response);
System.out.print("Enter tram tracker ID >> ");
String word = keyboard.nextLine(); // <-- read a line. Bad idea to leave trailing
// new lines.
try (Scanner route = new Scanner(inFile)) {
while (route.hasNextLine()) {
String[] line = route.nextLine().split("\\^");
String street = line[0];
String stopNum = line[1];
String trkID = line[2];
String road = line[3];
String suburb = line[4];
if (!trkID.equals(word)) {
continue;
}
System.out.printf("street: %s, stop: %s, id: %s, road: %s, suburb: %s%n",
street, stopNum, trkID, road, suburb);
}
}
Your code print everything in the file.
To print a line with an given ID:
You can first buffer all lines of the file into a ArrayList like this in the main method:
ArrayList<String> lines = new ArrayList<>();
while (route.hasNextLine())
{
lines.add(route.nextLine());
}
Then create a method to find a line with a specific ID:
public static int find(ArrayList information, int ID)
{
String idString = "" + ID;
ListIterator<String> li = information.listIterator();
String currentLine = "";
int index = 0;
while(li.hasNext())
{
currentLine = li.next();
int count = 0;
int index1 = 0;
int index2 = 0;
/*Trying to locate the string between the 2nd and 3rd ^ */
for(int i = 0; i < currentLine.length(); i++)
{
if(currentLine.substring(i, i+1).equals("^"))
{
count++;
if(count == 2)
index1 = i;
else if(count == 3)
{
index2 = i;
break;
}
}
}
if(currentLine.substring(index1+1, index2).equals (idString))
return(index);
index++;
}
//If no such ID found, return -1;
return -1;
}
In the main method:
System.out.println("enter an ID")
int ID = Integer.parseInt(Keyboard.next());
int lineNumber = find(lines, ID);
if(lineNumber == -1)
System.out.println("no information found");
else
System.out.println(lines.get(lineNumber));

Best way to handle awt.Image buffering in JavaFX

I have a class that takes a String parameter and performs a google search, then it gets the ten images and puts them in an array, that is then handled by another method in the same class. Using Javafx.scene.image would probably allow me to implement the buffering progress easily, but there is a bug with JavaFX Image, that misinterprets the color encoding of normal Images, and saves a weird looking image to the hard drive, so I just decided to use awt.Image.
This is the image search class:
public class GoogleCustomSearch {
static String key = //custom google id;
static String cx = // also a custom google id;
static String searchType = "image";
static java.awt.Image[] publicImageArray;
public static java.awt.Image[] Search(String searchParameter,int start) throws IOException, URISyntaxException{
String formatedText = URLEncoder.encode(searchParameter,"UTF-8");
URL url = new URL("https://www.googleapis.com/customsearch/v1?" + "key=" +key + "&cx=" +cx + "&q=" +formatedText + "&searchType=" +searchType +"&imgSize=medium" + "&start=" + start + "&num=10");
System.out.println(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
BufferedReader br = new BufferedReader(new InputStreamReader( ( conn.getInputStream() ) ) );
GResults results = new Gson().fromJson(br, GResults.class);
java.awt.Image [] imageArray = new java.awt.Image[10];
//JProgressBar prb = new JProgressBar();
//MediaTracker loadTracker = new MediaTracker(prb);
for(int i = 0; i<10; i++){
try {
imageArray[i] = ImageIO.read(new URL(results.getLink(i)));
}catch (java.io.IOException e){
imageArray[i] = ImageIO.read(new File("C:\\Users\\FILIP.D\\IdeaProjects\\Manual_Artwork\\src\\MAT - NoImage.jpg"));
}
}
conn.disconnect();
return imageArray;
}
public static BufferedImage getImage(String searchPar, int index, boolean newSearch) throws IOException, URISyntaxException {
int adaptedIndex;
int start;
BufferedImage bimage;
if(index<10){
adaptedIndex = index;
start = 1;
}else if (index<20){
start = 11;
adaptedIndex = index % 10;
if(index == 10){
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
}
}else if(index < 30){
start = 21;
adaptedIndex = index % 10;
if (index == 20) {
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
}
}else{
adaptedIndex = index % 10;
start = 21; //ovo ce posle 30 da ga vrti u loop prvih 10
}
if(newSearch){
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
return bimage = (BufferedImage) publicImageArray[adaptedIndex];
}else{
return bimage = (BufferedImage) publicImageArray[adaptedIndex];
}
}
public static RenderedImage getLiveImage (int index){
return (RenderedImage) publicImageArray[index % 10];
}
}
And this is the snippet of the main GUI class that just handles opening the new image in the array
private void nextImageResult() throws IOException, URISyntaxException {
if(imgNr == -1){
imgNr++;
changeImage(SwingFXUtils.toFXImage(GoogleCustomSearch.getImage(oppenedTrack.getArtistName() + "+" + oppenedTrack.getTrackName(),imgNr,true),null));
}else{
imgNr++;
changeImage(SwingFXUtils.toFXImage(GoogleCustomSearch.getImage(oppenedTrack.getArtistName() + "+" + oppenedTrack.getTrackName(),imgNr,false),null));
}
}
To summarise, I need a proper way to show a progress bar in the place of the image before it loads, and it needs not to hang the UI, for which I can use Task. I can optimise the loading of the array with MediaTracker, so it can prioritize loading the first few images first.

How to get a substring in some length for special chars like Chinese

For example, I can get 80 chars with {description?substring(0, 80)} if description is in English, but for Chinese chars, I can get only about 10 chars, and there is a garbage char at the end always.
How can I get 80 chars for any language?
FreeMarker relies on String#substring to do the actual (UTF-16-chars-based?) substring calculation, which doesn't work well with Chinese characters. Instead one should uses Unicode code points. Based on this post and FreeMarker's own substring builtin I hacked together a FreeMarker TemplateMethodModelEx implementation which operates on code points:
public class CodePointSubstring implements TemplateMethodModelEx {
#Override
public Object exec(List args) throws TemplateModelException {
int argCount = args.size(), left = 0, right = 0;
String s = "";
if (argCount != 3) {
throw new TemplateModelException(
"Error: Expecting 1 string and 2 numerical arguments here");
}
try {
TemplateScalarModel tsm = (TemplateScalarModel) args.get(0);
s = tsm.getAsString();
} catch (ClassCastException cce) {
String mess = "Error: Expecting numerical argument here";
throw new TemplateModelException(mess);
}
try {
TemplateNumberModel tnm = (TemplateNumberModel) args.get(1);
left = tnm.getAsNumber().intValue();
tnm = (TemplateNumberModel) args.get(2);
right = tnm.getAsNumber().intValue();
} catch (ClassCastException cce) {
String mess = "Error: Expecting numerical argument here";
throw new TemplateModelException(mess);
}
return new SimpleScalar(getSubstring(s, left, right));
}
private String getSubstring(String s, int start, int end) {
int[] codePoints = new int[end - start];
int length = s.length();
int i = 0;
for (int offset = 0; offset < length && i < codePoints.length;) {
int codepoint = s.codePointAt(offset);
if (offset >= start) {
codePoints[i] = codepoint;
i++;
}
offset += Character.charCount(codepoint);
}
return new String(codePoints, 0, i);
}
}
You can put an instance of it into your data model root, e.g.
SimpleHash root = new SimpleHash();
root.put("substring", new CodePointSubstring());
template.process(root, ...);
and use the custom substring method in FTL:
${substring(description, 0, 80)}
I tested it with non-Chinese characters, which still worked, but so far I haven't tried it with Chinese characters. Maybe you want to give it a try.

SHA1 with salt on windows phone 7

I have some some time now reshearchd how to encode a password to SHA1 with a salt.
The is the code i used on my web application part, but it will not work on a phone environment.
public class Password
{
private string _password;
private int _salt;
public Password(string strPassword, int nSalt)
{
_password = strPassword;
_salt = nSalt;
}
public string ComputeSaltedHash()
{
// Create Byte array of password string
ASCIIEncoding encoder = new ASCIIEncoding();
Byte[] _secretBytes = encoder.GetBytes(_password);
// Create a new salt
Byte[] _saltBytes = new Byte[4];
_saltBytes[0] = (byte)(_salt >> 24);
_saltBytes[1] = (byte)(_salt >> 16);
_saltBytes[2] = (byte)(_salt >> 8);
_saltBytes[3] = (byte)(_salt);
// append the two arrays
Byte[] toHash = new Byte[_secretBytes.Length + _saltBytes.Length];
Array.Copy(_secretBytes, 0, toHash, 0, _secretBytes.Length);
Array.Copy(_saltBytes, 0, toHash, _secretBytes.Length, _saltBytes.Length);
SHA1 sha1 = SHA1.Create();
Byte[] computedHash = sha1.ComputeHash(toHash);
return encoder.GetString(computedHash);
}
public static int CreateRandomSalt()
{
Byte[] _saltBytes = new Byte[4];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(_saltBytes);
return ((((int)_saltBytes[0]) << 24) + (((int)_saltBytes[1]) << 16) +
(((int)_saltBytes[2]) << 8) + ((int)_saltBytes[3]));
}
public static string CreateRandomPassword(int PasswordLength)
{
String _allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ23456789!\"#ยค%&/()=?$+-_.,;'*";
Byte[] randomBytes = new Byte[PasswordLength];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(randomBytes);
char[] chars = new char[PasswordLength];
int allowedCharCount = _allowedChars.Length;
for (int i = 0; i < PasswordLength; i++)
{
chars[i] = _allowedChars[(int)randomBytes[i] % allowedCharCount];
}
return new string(chars);
}
}
Silverlight and Windows Phone 7 do not have an ASCIIEncoding. I suggest you use the UTF8Encoding instead. If you are certain that your passwords are always within the ASCII range then this encoding will work the same as the ASCIIEncoding would of had it been present.
If on the other hand you cannot guarantee that passwords are always within the ASCII range then you would need to make sure both ends hash using the UTF8Encoding to ensure generated hashs are the same.

Resources