or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-processing.mdcopy-paste-detection.mdcore-analysis.mdindex.mdlanguage-framework.mdproperties-system.mdrendering-system.mdreporting-system.mdrule-system.mdutilities.md

utilities.mddocs/

0

# Utilities and Support Classes

1

2

The Utilities module provides essential helper classes and functions for common operations including parameter validation, string manipulation, file handling, version management, and other utility functions used throughout PMD Core.

3

4

## Capabilities

5

6

### Assertion Utilities

7

8

Parameter validation and assertion utilities for defensive programming and error handling.

9

10

```java { .api }

11

/**

12

* Utility methods for parameter validation and assertions.

13

* Provides consistent error messages and null checking across PMD.

14

*/

15

public final class AssertionUtil {

16

17

/**

18

* Check parameter is not null and return it

19

* @param paramName Name of parameter for error message

20

* @param param Parameter value to check

21

* @return The parameter value if not null

22

* @throws IllegalArgumentException if parameter is null

23

*/

24

static <T> T requireParamNotNull(String paramName, T param);

25

26

/**

27

* Check collection contains no null values

28

* @param paramName Name of parameter for error message

29

* @param collection Collection to validate

30

* @throws IllegalArgumentException if collection contains null elements

31

*/

32

static <T> void requireContainsNoNullValue(String paramName, Collection<T> collection);

33

34

/**

35

* Create "unreachable code" assertion error

36

* @return AssertionError indicating code should not be reached

37

*/

38

static AssertionError shouldNotReachHere();

39

40

/**

41

* Create "unreachable code" assertion error with message

42

* @param message Descriptive message for the error

43

* @return AssertionError with custom message

44

*/

45

static AssertionError shouldNotReachHere(String message);

46

47

/**

48

* Create "unreachable code" assertion error with message and cause

49

* @param message Descriptive message for the error

50

* @param cause Underlying cause of the error

51

* @return AssertionError with message and cause

52

*/

53

static AssertionError shouldNotReachHere(String message, Throwable cause);

54

}

55

```

56

57

**Usage Examples:**

58

59

```java

60

import net.sourceforge.pmd.util.AssertionUtil;

61

import java.util.List;

62

import java.util.Arrays;

63

64

// Using assertion utilities in methods

65

public class ValidationExample {

66

67

public void processData(String name, List<String> items, Object config) {

68

// Validate required parameters

69

name = AssertionUtil.requireParamNotNull("name", name);

70

items = AssertionUtil.requireParamNotNull("items", items);

71

config = AssertionUtil.requireParamNotNull("config", config);

72

73

// Validate collection contents

74

AssertionUtil.requireContainsNoNullValue("items", items);

75

76

// Process with confidence that parameters are valid

77

processValidatedData(name, items, config);

78

}

79

80

private void processValidatedData(String name, List<String> items, Object config) {

81

// Implementation assumes all parameters are non-null

82

System.out.printf("Processing %s with %d items%n", name, items.size());

83

}

84

85

public String handleDifferentCases(int caseType) {

86

switch (caseType) {

87

case 1:

88

return "Case 1";

89

case 2:

90

return "Case 2";

91

case 3:

92

return "Case 3";

93

default:

94

// This should never happen based on our design

95

throw AssertionUtil.shouldNotReachHere(

96

"Unexpected case type: " + caseType);

97

}

98

}

99

100

public void demonstrateErrorHandling() {

101

try {

102

processData(null, Arrays.asList("a", "b"), new Object());

103

} catch (IllegalArgumentException e) {

104

System.err.println("Expected error: " + e.getMessage());

105

}

106

107

try {

108

processData("test", Arrays.asList("a", null, "c"), new Object());

109

} catch (IllegalArgumentException e) {

110

System.err.println("Expected error: " + e.getMessage());

111

}

112

113

try {

114

handleDifferentCases(99); // Invalid case

115

} catch (AssertionError e) {

116

System.err.println("Unreachable code error: " + e.getMessage());

117

}

118

}

119

}

120

121

// Using in custom rule implementation

122

public class CustomRuleExample extends AbstractRule {

123

124

@Override

125

public void apply(List<? extends Node> nodes, RuleContext ctx) {

126

// Validate inputs

127

nodes = AssertionUtil.requireParamNotNull("nodes", nodes);

128

ctx = AssertionUtil.requireParamNotNull("ctx", ctx);

129

AssertionUtil.requireContainsNoNullValue("nodes", nodes);

130

131

// Safe to proceed with analysis

132

for (Node node : nodes) {

133

analyzeNode(node, ctx);

134

}

135

}

136

137

private void analyzeNode(Node node, RuleContext ctx) {

138

// Implementation can assume node and ctx are non-null

139

if (node.getNumChildren() == 0) {

140

ctx.addViolation(node, "Empty node found");

141

}

142

}

143

}

144

```

145

146

### String Utilities

147

148

String manipulation utilities for common text processing operations.

149

150

```java { .api }

151

/**

152

* String manipulation utilities for common text operations.

153

* Provides null-safe methods for string validation and processing.

154

*/

155

public final class StringUtil {

156

157

/**

158

* Check if string is null or empty

159

* @param str String to check

160

* @return true if string is null or has length 0

161

*/

162

static boolean isEmpty(String str);

163

164

/**

165

* Check if string is not null and not empty

166

* @param str String to check

167

* @return true if string is not null and has length > 0

168

*/

169

static boolean isNotEmpty(String str);

170

171

/**

172

* Check if string is null, empty, or contains only whitespace

173

* @param str String to check

174

* @return true if string is null, empty, or whitespace-only

175

*/

176

static boolean isBlank(String str);

177

178

/**

179

* Check if string has non-whitespace content

180

* @param str String to check

181

* @return true if string contains non-whitespace characters

182

*/

183

static boolean isNotBlank(String str);

184

185

/**

186

* Quote string for MessageFormat (escape single quotes)

187

* @param msg String to quote for MessageFormat usage

188

* @return String with single quotes escaped

189

*/

190

static String quoteMessageFormat(String msg);

191

192

/**

193

* Replace all occurrences of substring

194

* @param original Source string

195

* @param find Substring to find

196

* @param replacement Replacement string

197

* @return String with all occurrences replaced

198

*/

199

static String replaceString(String original, String find, String replacement);

200

201

/**

202

* Split string by character separator

203

* @param str String to split

204

* @param separator Character to split on

205

* @return List of split parts (empty list if input is null/empty)

206

*/

207

static List<String> split(String str, char separator);

208

}

209

```

210

211

**Usage Examples:**

212

213

```java

214

import net.sourceforge.pmd.util.StringUtil;

215

import java.util.List;

216

217

// Using string utilities

218

public class StringProcessingExample {

219

220

public void validateInput(String userInput) {

221

if (StringUtil.isEmpty(userInput)) {

222

throw new IllegalArgumentException("Input cannot be empty");

223

}

224

225

if (StringUtil.isBlank(userInput)) {

226

System.out.println("Warning: Input is only whitespace");

227

return;

228

}

229

230

// Process valid input

231

processValidInput(userInput.trim());

232

}

233

234

public void processConfiguration(String configValue) {

235

// Check for meaningful content

236

if (StringUtil.isNotBlank(configValue)) {

237

System.out.printf("Processing config: '%s'%n", configValue);

238

239

// Split configuration values

240

List<String> parts = StringUtil.split(configValue, ',');

241

System.out.printf("Configuration has %d parts:%n", parts.size());

242

243

for (int i = 0; i < parts.size(); i++) {

244

String part = parts.get(i).trim();

245

if (StringUtil.isNotEmpty(part)) {

246

System.out.printf(" Part %d: %s%n", i + 1, part);

247

}

248

}

249

} else {

250

System.out.println("No configuration provided");

251

}

252

}

253

254

public String formatMessage(String template, String userValue) {

255

// Prepare message for MessageFormat

256

String quotedTemplate = StringUtil.quoteMessageFormat(template);

257

258

// Replace placeholder with actual value

259

return StringUtil.replaceString(quotedTemplate, "{value}", userValue);

260

}

261

262

public void demonstrateStringOperations() {

263

// Test empty/blank detection

264

testString(null, "null string");

265

testString("", "empty string");

266

testString(" ", "whitespace string");

267

testString("hello", "normal string");

268

269

// Test splitting

270

String csvData = "apple,banana,cherry,date";

271

List<String> fruits = StringUtil.split(csvData, ',');

272

System.out.printf("CSV '%s' split into: %s%n", csvData, fruits);

273

274

// Test replacement

275

String original = "Hello {name}, welcome to {place}!";

276

String replaced = StringUtil.replaceString(original, "{name}", "Alice");

277

replaced = StringUtil.replaceString(replaced, "{place}", "PMD");

278

System.out.printf("Template: %s%nResult: %s%n", original, replaced);

279

280

// Test MessageFormat quoting

281

String messageTemplate = "Don't use 'System.out.println'";

282

String quoted = StringUtil.quoteMessageFormat(messageTemplate);

283

System.out.printf("Original: %s%nQuoted: %s%n", messageTemplate, quoted);

284

}

285

286

private void testString(String str, String description) {

287

System.out.printf("%s:%n", description);

288

System.out.printf(" isEmpty: %b%n", StringUtil.isEmpty(str));

289

System.out.printf(" isNotEmpty: %b%n", StringUtil.isNotEmpty(str));

290

System.out.printf(" isBlank: %b%n", StringUtil.isBlank(str));

291

System.out.printf(" isNotBlank: %b%n", StringUtil.isNotBlank(str));

292

}

293

294

private void processValidInput(String input) {

295

System.out.printf("Processing valid input: '%s'%n", input);

296

}

297

}

298

299

// Using in rule message formatting

300

public class MessageFormattingExample {

301

302

public void formatRuleMessage(String template, Object... args) {

303

// Quote template for MessageFormat

304

String quotedTemplate = StringUtil.quoteMessageFormat(template);

305

306

// Format with arguments

307

String message = MessageFormat.format(quotedTemplate, args);

308

System.out.println("Formatted message: " + message);

309

}

310

311

public void processRuleViolation(RuleViolation violation) {

312

String description = violation.getDescription();

313

314

if (StringUtil.isNotBlank(description)) {

315

// Clean up the description

316

description = description.trim();

317

318

// Remove PMD-specific markers if present

319

description = StringUtil.replaceString(description, "PMD:", "");

320

description = description.trim();

321

322

System.out.printf("Clean violation: %s%n", description);

323

}

324

}

325

}

326

```

327

328

### Version Management

329

330

Version information and utilities for PMD versioning and compatibility checking.

331

332

```java { .api }

333

/**

334

* PMD version information and utilities.

335

* Provides access to current version and version-related operations.

336

*/

337

public final class PMDVersion {

338

339

/**

340

* Current PMD version string

341

*/

342

public static final String VERSION;

343

344

/**

345

* Get next expected major version

346

* @return Next major version string

347

*/

348

static String getNextMajorRelease();

349

350

/**

351

* Check if current version is unknown

352

* @return true if version information is not available

353

*/

354

static boolean isUnknown();

355

356

/**

357

* Check if current version is a snapshot build

358

* @return true if version contains snapshot indicators

359

*/

360

static boolean isSnapshot();

361

362

/**

363

* Get full version string with metadata

364

* @return Complete version string including build information

365

*/

366

static String getFullVersionName();

367

}

368

```

369

370

**Usage Examples:**

371

372

```java

373

import net.sourceforge.pmd.PMDVersion;

374

375

// Working with version information

376

public class VersionExample {

377

378

public void displayVersionInfo() {

379

System.out.println("PMD Version Information:");

380

System.out.printf(" Current version: %s%n", PMDVersion.VERSION);

381

System.out.printf(" Full version: %s%n", PMDVersion.getFullVersionName());

382

System.out.printf(" Next major: %s%n", PMDVersion.getNextMajorRelease());

383

System.out.printf(" Is snapshot: %b%n", PMDVersion.isSnapshot());

384

System.out.printf(" Is unknown: %b%n", PMDVersion.isUnknown());

385

}

386

387

public void checkCompatibility(String requiredVersion) {

388

String currentVersion = PMDVersion.VERSION;

389

390

if (PMDVersion.isUnknown()) {

391

System.out.println("Warning: PMD version is unknown");

392

return;

393

}

394

395

if (PMDVersion.isSnapshot()) {

396

System.out.println("Note: Using snapshot version - features may be unstable");

397

}

398

399

// Simple version comparison (real implementation would be more sophisticated)

400

if (currentVersion.equals(requiredVersion)) {

401

System.out.printf("✓ Version %s matches requirement%n", currentVersion);

402

} else {

403

System.out.printf("⚠ Version %s does not match requirement %s%n",

404

currentVersion, requiredVersion);

405

}

406

}

407

408

public void generateBuildInfo() {

409

System.out.println("Build Information:");

410

System.out.printf("PMD Core %s%n", PMDVersion.getFullVersionName());

411

412

if (PMDVersion.isSnapshot()) {

413

System.out.println("This is a development build - not for production use");

414

} else {

415

System.out.println("This is a release build");

416

}

417

}

418

}

419

```

420

421

### Rendering Utilities

422

423

Extended rendering system with comprehensive output format support including XML, HTML, JSON, CSV, and specialized formats.

424

425

```java { .api }

426

/**

427

* Extensible rendering framework for formatting analysis reports.

428

* Provides multiple output formats with customizable properties.

429

*/

430

public interface Renderer extends PropertySource {

431

432

/**

433

* Get renderer name/identifier

434

* @return Unique name for the renderer

435

*/

436

String getName();

437

438

/**

439

* Set renderer name

440

* @param name Unique identifier for renderer

441

*/

442

void setName(String name);

443

444

/**

445

* Get renderer description

446

* @return Human-readable description of renderer purpose

447

*/

448

String getDescription();

449

450

/**

451

* Set renderer description

452

* @param description Description of renderer functionality

453

*/

454

void setDescription(String description);

455

456

/**

457

* Get default file extension for output

458

* @return File extension without dot (e.g., "xml", "html")

459

*/

460

String defaultFileExtension();

461

462

/**

463

* Check if suppressed violations are shown

464

* @return true if renderer includes suppressed violations

465

*/

466

boolean isShowSuppressedViolations();

467

468

/**

469

* Set whether to show suppressed violations

470

* @param show true to include suppressed violations in output

471

*/

472

void setShowSuppressedViolations(boolean show);

473

474

/**

475

* Set output writer for rendering

476

* @param writer Writer for formatted output

477

*/

478

void setWriter(Writer writer);

479

480

/**

481

* Set report file path (alternative to setWriter)

482

* @param reportFile Path to output file

483

*/

484

void setReportFile(String reportFile);

485

486

/**

487

* Create analysis listener for receiving events

488

* @return GlobalAnalysisListener that forwards to this renderer

489

*/

490

GlobalAnalysisListener newListener();

491

492

/**

493

* Start rendering process

494

*/

495

void start();

496

497

/**

498

* End rendering process

499

*/

500

void end();

501

502

/**

503

* Flush any buffered output

504

*/

505

void flush();

506

}

507

```

508

509

## Types

510

511

```java { .api }

512

/**

513

* File identifier and metadata

514

*/

515

interface FileId {

516

517

/**

518

* Get absolute file path

519

* @return Absolute path to the file

520

*/

521

String getAbsolutePath();

522

523

/**

524

* Get display name for reports

525

* @return User-friendly file name for display

526

*/

527

String getDisplayName();

528

529

/**

530

* Get file URI

531

* @return URI representation of file location

532

*/

533

URI getUri();

534

535

/**

536

* Create FileId from path-like string

537

* @param pathLike String representing file path

538

* @return FileId instance

539

*/

540

static FileId fromPathLikeString(String pathLike);

541

542

/**

543

* Create FileId from Path object

544

* @param path Path object representing file

545

* @return FileId instance

546

*/

547

static FileId fromPath(Path path);

548

}

549

550

/**

551

* Text document representation

552

*/

553

interface TextDocument {

554

555

/**

556

* Get complete document text

557

* @return Full text content

558

*/

559

String getText();

560

561

/**

562

* Get text for specific region

563

* @param region TextRegion to extract

564

* @return Text content for region

565

*/

566

String getText(TextRegion region);

567

568

/**

569

* Get line content by number

570

* @param lineNumber One-based line number

571

* @return Content of specified line

572

*/

573

String getLine(int lineNumber);

574

575

/**

576

* Get total line count

577

* @return Number of lines in document

578

*/

579

int getLineCount();

580

581

/**

582

* Get file identifier

583

* @return FileId for this document

584

*/

585

FileId getFileId();

586

}

587

588

/**

589

* Collection utilities for common operations

590

*/

591

final class CollectionUtil {

592

593

/**

594

* Create immutable list from array

595

* @param items Array elements

596

* @return Unmodifiable List containing elements

597

*/

598

static <T> List<T> listOf(T... items);

599

600

/**

601

* Check if collection is null or empty

602

* @param collection Collection to check

603

* @return true if collection is null or empty

604

*/

605

static boolean isEmpty(Collection<?> collection);

606

607

/**

608

* Get first element of list

609

* @param list List to query

610

* @return First element or null if empty

611

*/

612

static <T> T first(List<T> list);

613

614

/**

615

* Get last element of list

616

* @param list List to query

617

* @return Last element or null if empty

618

*/

619

static <T> T last(List<T> list);

620

}

621

622

/**

623

* I/O utilities for file operations

624

*/

625

final class IOUtil {

626

627

/**

628

* Read entire file as string

629

* @param file File to read

630

* @param charset Character encoding to use

631

* @return File contents as string

632

*/

633

static String readFileToString(File file, Charset charset) throws IOException;

634

635

/**

636

* Write string to file

637

* @param file Target file

638

* @param content Content to write

639

* @param charset Character encoding to use

640

*/

641

static void writeStringToFile(File file, String content, Charset charset) throws IOException;

642

643

/**

644

* Close resource quietly (ignoring exceptions)

645

* @param closeable Resource to close

646

*/

647

static void closeQuietly(Closeable closeable);

648

649

/**

650

* Copy input stream to output stream

651

* @param input Source stream

652

* @param output Target stream

653

* @return Number of bytes copied

654

*/

655

static long copy(InputStream input, OutputStream output) throws IOException;

656

}

657

658

/**

659

* Date/time utilities for timestamps

660

*/

661

final class DateTimeUtil {

662

663

/**

664

* Format timestamp for reports

665

* @param timestamp Timestamp to format

666

* @return Formatted timestamp string

667

*/

668

static String formatTimestamp(long timestamp);

669

670

/**

671

* Get current timestamp

672

* @return Current system time in milliseconds

673

*/

674

static long getCurrentTimestamp();

675

676

/**

677

* Parse ISO date string

678

* @param dateString ISO-formatted date

679

* @return Parsed timestamp

680

*/

681

static long parseISODate(String dateString);

682

}

683

684

/**

685

* System utilities for environment access

686

*/

687

final class SystemUtil {

688

689

/**

690

* Get system property with default

691

* @param key Property key

692

* @param defaultValue Default if property not set

693

* @return Property value or default

694

*/

695

static String getSystemProperty(String key, String defaultValue);

696

697

/**

698

* Check if running on Windows

699

* @return true if Windows operating system

700

*/

701

static boolean isWindows();

702

703

/**

704

* Get available processor count

705

* @return Number of available processors

706

*/

707

static int getAvailableProcessors();

708

709

/**

710

* Get total system memory

711

* @return Total memory in bytes

712

*/

713

static long getTotalMemory();

714

}

715

716

/**

717

* Mathematical utilities for calculations

718

*/

719

final class MathUtil {

720

721

/**

722

* Calculate percentage

723

* @param part Numerator value

724

* @param total Denominator value

725

* @return Percentage (0-100)

726

*/

727

static double percentage(long part, long total);

728

729

/**

730

* Clamp value to range

731

* @param value Value to clamp

732

* @param min Minimum allowed value

733

* @param max Maximum allowed value

734

* @return Clamped value within range

735

*/

736

static int clamp(int value, int min, int max);

737

738

/**

739

* Check if number is in range (inclusive)

740

* @param value Value to check

741

* @param min Minimum value

742

* @param max Maximum value

743

* @return true if value is within range

744

*/

745

static boolean inRange(int value, int min, int max);

746

}

747

```