1010import java .net .URL ;
1111import java .net .URLEncoder ;
1212import java .nio .charset .Charset ;
13+ import java .util .ArrayList ;
1314import java .util .Date ;
1415import java .util .HashMap ;
16+ import java .util .List ;
1517import java .util .Map ;
18+ import java .util .Map .Entry ;
1619import java .util .Random ;
1720import javax .json .JsonValue ;
1821import javax .xml .bind .DatatypeConverter ;
@@ -99,6 +102,7 @@ public class PiwikRequest{
99102 private static final long REQUEST_DATETIME_AUTH_LIMIT = 14400000L ;
100103
101104 private final Map <String , Object > parameters = new HashMap <>();
105+ private final Map <String , List > customTrackingParameters = new HashMap <>();
102106
103107 /**
104108 * Create a new request from the id of the site being tracked and the full
@@ -396,6 +400,51 @@ public Integer getCurrentSecond(){
396400 public void setCurrentSecond (Integer currentSecond ){
397401 setParameter (CURRENT_SECOND , currentSecond );
398402 }
403+
404+ /**
405+ * Set a custom tracking parameter whose toString() value will be sent to
406+ * the Piwik server. These parameters are stored separately from named Piwik
407+ * parameters, meaning it is not possible to overwrite or clear named Piwik
408+ * parameters with this method. A custom parameter that has the same name
409+ * as a set named Piwik parameter will be sent in addition to the named parameter.
410+ * @param key the parameter's key
411+ * @param value the parameter's value. Removes the parameter if null
412+ */
413+ public void setCustomTrackingParameter (String key , Object value ){
414+ if (value == null ){
415+ customTrackingParameters .remove (key );
416+ }
417+ else {
418+ List l = new ArrayList <>();
419+ l .add (value );
420+ customTrackingParameters .put (key , l );
421+ }
422+ }
423+
424+ /**
425+ * Add a custom tracking parameter to the specified key. This allows users
426+ * to have multiple parameters with the same name and different values,
427+ * commonly used during situations where list parameters are needed
428+ * @param key the parameter's key
429+ * @param value the parameter's value. Cannot be null
430+ */
431+ public void addCustomTrackingParameter (String key , Object value ){
432+ if (value == null ){
433+ throw new NullPointerException ("Cannot add a null custom tracking parameter." );
434+ }
435+ else {
436+ List l = customTrackingParameters .getOrDefault (key , new ArrayList <>());
437+ l .add (value );
438+ customTrackingParameters .put (key , l );
439+ }
440+ }
441+
442+ /**
443+ * Removes all custom tracking parameters
444+ */
445+ public void clearCustomTrackingParameter (){
446+ customTrackingParameters .clear ();
447+ }
399448
400449 /**
401450 * Get the resolution of the device
@@ -1441,14 +1490,24 @@ public void setVisitorVisitCount(Integer visitorVisitCount){
14411490
14421491 public String getQueryString (){
14431492 StringBuilder sb = new StringBuilder ();
1444- for (Map . Entry <String , Object > parameter : parameters .entrySet ()){
1493+ for (Entry <String , Object > parameter : parameters .entrySet ()){
14451494 if (sb .length () > 0 ){
14461495 sb .append ("&" );
14471496 }
14481497 sb .append (parameter .getKey ());
14491498 sb .append ("=" );
14501499 sb .append (parameter .getValue ().toString ());
14511500 }
1501+ for (Entry <String , List > customTrackingParameter : customTrackingParameters .entrySet ()){
1502+ for (Object o : customTrackingParameter .getValue ()){
1503+ if (sb .length () > 0 ){
1504+ sb .append ("&" );
1505+ }
1506+ sb .append (customTrackingParameter .getKey ());
1507+ sb .append ("=" );
1508+ sb .append (o .toString ());
1509+ }
1510+ }
14521511
14531512 return sb .toString ();
14541513 }
@@ -1459,18 +1518,38 @@ public String getQueryString(){
14591518 */
14601519 public String getUrlEncodedQueryString (){
14611520 StringBuilder sb = new StringBuilder ();
1462- for (Map . Entry <String , Object > parameter : parameters .entrySet ()){
1521+ for (Entry <String , Object > parameter : parameters .entrySet ()){
14631522 if (sb .length () > 0 ){
14641523 sb .append ("&" );
14651524 }
1466- sb .append (parameter .getKey ());
1467- sb .append ("=" );
14681525 try {
1469- sb .append (URLEncoder .encode (parameter .getValue ().toString (), "UTF-8" ));
1470- } catch (UnsupportedEncodingException e ) {
1526+ StringBuilder sb2 = new StringBuilder ();
1527+ sb2 .append (parameter .getKey ());
1528+ sb2 .append ("=" );
1529+ sb2 .append (URLEncoder .encode (parameter .getValue ().toString (), "UTF-8" ));
1530+ sb .append (sb2 );
1531+ }
1532+ catch (UnsupportedEncodingException e ) {
14711533 System .err .println (e .getMessage ());
14721534 }
14731535 }
1536+ for (Entry <String , List > customTrackingParameter : customTrackingParameters .entrySet ()){
1537+ for (Object o : customTrackingParameter .getValue ()){
1538+ if (sb .length () > 0 ){
1539+ sb .append ("&" );
1540+ }
1541+ try {
1542+ StringBuilder sb2 = new StringBuilder ();
1543+ sb2 .append (URLEncoder .encode (customTrackingParameter .getKey (), "UTF-8" ));
1544+ sb2 .append ("=" );
1545+ sb2 .append (URLEncoder .encode (o .toString (), "UTF-8" ));
1546+ sb .append (sb2 );
1547+ }
1548+ catch (UnsupportedEncodingException e ) {
1549+ System .err .println (e .getMessage ());
1550+ }
1551+ }
1552+ }
14741553
14751554 return sb .toString ();
14761555 }
0 commit comments